##--------------------------------------------------------------------------------------------------------##
## The Effects of Exposure to New Electoral Rules: Field Experimental Evidence from Sierra Leone           #
## Avi Ahuja and Gwyneth McClendon, NYU Politics                                                           #
## Replication Code for American Political Science Review                                                  #
## All code appears in order of tables in the main paper and appendix                                      #
##--------------------------------------------------------------------------------------------------------##

# 0. Load required packages --

library(readr)
library(dplyr)
library(ggplot2)
library(vtable)
library(tidyverse) 
library(modelsummary)
library(mediation)
library(broom)
library(kableExtra)
library(stargazer)
library(broom)
library(sf)
library(car)
library(osmdata)
library(leaflet)
library(lmtest)
library(sandwich)
library(forcats)
library(readxl)
library(survey)
conflicted::conflict_prefer("select", "dplyr")
conflicted::conflict_prefer("filter", "dplyr")
conflicted::conflict_prefer("mutate", "dplyr")
conflicted::conflict_prefer("row_number", "dplyr")
#setwd("~/Dropbox/Valence Issues in African Politics/Code/Replication")



# 1. Load required datasets for analysis --

# 1.1 Baseline and panel data (de-identified)
baseline_data <- read_csv("cleaned_baseline_data.csv")
merged_data <- read_csv("merged_final_data.csv")

## 1.2 Load survey experiment data
analysis_df <- readr::read_csv("survey_experiment_data.csv")

## 1.3 SL 2018 election results and SL 2023 election results
SL_2018_results <-  readr::read_csv("SL_2018_results.csv")
SL_2023_results <- read_excel("2023 district results.xlsx")

## 1.4 District shapefile of SL
districts.shp <- st_read("sle_adm_gov_ocha_20231215_ab_shp/sle_admbnda_adm2_gov_ocha_20231215.shp") 




#  --------------------------------------------------------------------------- ##
# --                        Main Article Tables                             -- ##
#  --------------------------------------------------------------------------- ##

# Table 1: Treatment Effects on Knowledge of Electoral Systems ----

# Knows MP elected through PR (column 1)
merged_data$knowspr_mp<-ifelse(merged_data$ballot_knowledge_mp=="Preferred party",1,0) 
summary(merged_data$knowspr_mp)
knowledge_mppr<-lm(merged_data$knowspr_mp~treatment_status+married+respondent_children_num,data=merged_data)
summary(knowledge_mppr)

# Knows President Elected through FPTP (column 2)
merged_data$knowspr_pres<-ifelse(merged_data$ballot_knowledge_president=="Preferred candidate",1,0) 
summary(merged_data$knowspr_pres)
knowledge_presfptp<-lm(merged_data$knowspr_pres~treatment_status+married+respondent_children_num,data=merged_data)
summary(knowledge_presfptp)

# Accurate Answers about Women's Representation (column 3)
merged_data$knowspr_women<-ifelse(merged_data$knowledge_women_system=="Agree with Statement 1",1,0) 
knowledge_prwomen<-lm(merged_data$knowspr_women~treatment_status+married+respondent_children_num,data=merged_data)
summary(knowledge_prwomen)

stargazer(knowledge_mppr, knowledge_presfptp, knowledge_prwomen, 
          title="Treatment Effects on Knowledge of Electoral Systems", align=TRUE, type = "text")




# ------------------------------------------------------------------------------------------------------------------ 
# Table 2: Treatment Effects on Political Participation ----

# Would vote (column 1)
merged_data$would_vote<-ifelse(merged_data$vote_tomorrow=="Yes, I would do this",1,0) 
summary(merged_data$would_vote)
turnout_gender<-lm(merged_data$would_vote~treatment_status*male+respondent_children_num+married,data=merged_data)
summary(turnout_gender)

# Vote wait time (column 2)
wait_hours_gender<-lm(merged_data$vote_wait_time~treatment_status*male+respondent_children_num+married,data=merged_data)
summary(wait_hours_gender)

# Would volunteer (column 3)
merged_data$would_volunteer<-ifelse(merged_data$vote_volunteer=="Yes, I would do this",1,0) 
summary(merged_data$would_volunteer)
volunteer_gender<-lm(merged_data$would_volunteer~treatment_status*male+respondent_children_num+married,data=merged_data)
summary(volunteer_gender)

# Encourage others (column 4)
merged_data$would_encourage<-ifelse(merged_data$vote_encourage_others=="Yes, I would do this",1,0) 
summary(merged_data$would_encourage)
encourage_gender<-lm(merged_data$would_encourage~treatment_status*male+respondent_children_num+married,data=merged_data)
summary(encourage_gender)

stargazer(turnout_gender,wait_hours_gender, volunteer_gender,encourage_gender,
          title="Effects on Participation by Gender", align=TRUE, type="text")




# ------------------------------------------------------------------------------------------------------------------ 
# Table 3: Treatment Effects on Approval of Different Campaign Appeals ----

# Strong approval of universal appeal (column 1)
universal_appeal_reg <- lm(liked_universal_appeal ~ treatment_status + respondent_children_num + married + 
                             party_ID + treatment_status:party_ID, data = merged_data)

# Strong approval of particularistic appeal (column 2)
targeted_appeal_reg <- lm(liked_targeted_appeal ~ treatment_status + respondent_children_num + married + 
                            party_ID + treatment_status:party_ID, data = merged_data)

# Strong approval of leader quality appeal (column 3)
leader_appeal_reg <- lm(liked_leader_appeal ~ treatment_status + respondent_children_num + married + 
                          party_ID + treatment_status:party_ID, data = merged_data)

stargazer(universal_appeal_reg, targeted_appeal_reg, leader_appeal_reg, 
          title = "Treatment Effects on Approval of Different Campaign Appeals", align = TRUE, type="text")




# ------------------------------------------------------------------------------------------------------------------ 
# Table 4: Treatment Effects on Trust in Elections -----

# Trust in Free and Fair Election (Column 1)
merged_data$election_hightrust_endline <- as.integer(merged_data$final_trust_election == 1)
election_hightrust_treat_regression <- lm(election_hightrust_endline ~ trust_group_indicator*treatment_status + respondent_children_num + married, 
                                          data=merged_data)

# Trust in Vote Counting Process (Column 2)
merged_data$trust_count <- as.integer(merged_data$final_trust_vote_counting == 1)
trustcount_treat_regression <- lm(trust_count ~ trust_group_indicator*treatment_status + respondent_children_num + married, data=merged_data)

# Trust in Peaceful Election (Column 3)
merged_data$trust_peace <- as.integer(merged_data$final_trust_peaceful_election == 1)
trustpeace_treat_regression <- lm(trust_peace ~ trust_group_indicator*treatment_status + respondent_children_num + married, data=merged_data)

# Create a list to store models
trust_order_models <- list(election_hightrust_treat_regression, 
                           trustcount_treat_regression, 
                           trustpeace_treat_regression
)

stargazer(trust_order_models, 
          title="Effects of Treatment on Trust in Elections", align=TRUE, type = "text")




#  --------------------------------------------------------------------------- ##
#                            Appendix Tables                                   ##
#  --------------------------------------------------------------------------- ##

# Note:  Most tables in Appendix Section B are available in separate files - see the README_APSR2025.rtf file for details.
# Appendix Section D -- file and data for Table D.1 uploaded separately using STATA - - see the README_APSR2025.rtf file for details.


#  ------------------------------------------------------------------------------------------------------ ##
## Appendix Section B: Additional Details about Sierra Leone Politics and the New Rules                    # 
#  ------------------------------------------------------------------------------------------------------ ##
## Note:  Most tables in Appendix Section B are available in separate files - see the README_APSR2025.rtf file for details.

## Table B3: District-Level Largest Party Shares and Margins Before and After PR Reform (2018 vs 2023) ---

# Compute largest party share and victory margin in 2023
district_2023_wide <- SL_2023_results %>%
  dplyr::select(District, Party, Percentage) %>%
  pivot_wider(
    names_from = Party, 
    values_from = Percentage, 
    values_fill = list(Percentage = 0)
  ) %>%
  mutate(
    largest_party_share_2023 = pmax(APC, SLPP, na.rm=TRUE),
    second_party_share_2023 = pmin(APC, SLPP, na.rm=TRUE),
    margin_2023 = largest_party_share_2023 - second_party_share_2023
  )

# Rank the candidates within each constituency by vote share in descending order 
SL_2018_results <- SL_2018_results %>%
  group_by(cst) %>%
  arrange(cst, desc(cvs1)) %>%
  mutate(rank = row_number())

# Calculate the total valid votes for each district (across all constituencies)
district_valid_votes <- SL_2018_results %>%
  group_by(sub, cst) %>%
  summarise(total_valid_votes_in_constituency = first(vv1)) %>%  # Extract the first occurrence of total valid votes for each constituency
  group_by(sub) %>%
  summarise(total_district_valid_votes = sum(total_valid_votes_in_constituency, na.rm = TRUE))

# Calculate the total votes for each party in each district and merge with district-level valid votes
district_aggregates <- SL_2018_results %>%
  group_by(sub, pty_n) %>%
  summarise(
    total_votes = sum(cv1, na.rm = TRUE)  # Total votes for each party in the district
  ) %>%
  left_join(district_valid_votes, by = "sub") %>%
  mutate(vote_share = total_votes / total_district_valid_votes) %>%
  ungroup()

# Create a data frame mapping each district to its seat allocation for the 2023 PR system
district_seat_allocation <- tibble(
  sub = c("Bo", "Bombali", "Bonthe", "Falaba", "Kailahun", "Kambia", "Karene", "Kenema", 
          "Koinadugu", "Kono", "Moyamba", "Port Loko", "Pujehun", "Tonkolili", 
          "Western Area Rural", "Western Area Urban"),
  seats = c(12, 8, 5, 4, 10, 6, 5, 12, 4, 10, 6, 10, 7, 10, 10, 16)
)

# Minimum threshold for seat allocation (11.9% vote share) under PR
pr_threshold <- 0.119

# Merge the district seat allocation with the district aggregates
district_aggregates <- district_aggregates %>%
  left_join(district_seat_allocation, by = "sub")

# Compute largest party share and victory margin in 2018
district_2018_summary <- district_aggregates %>%
  group_by(sub) %>%
  arrange(sub, desc(vote_share)) %>%
  summarise(
    SLPP = sum(vote_share[pty_n == "Sierra Leone People's Party (SLPP)"]) * 100,
    APC = sum(vote_share[pty_n == "All People's Congress (APC)"]) * 100,
    largest_party_share_2018 = first(vote_share) * 100,
    second_party_share_2018 = nth(vote_share, 2, default = 0) * 100,
    margin_2018 = largest_party_share_2018 - second_party_share_2018
  ) %>%
  ungroup()

# Renaming variables for consistency
district_2018_summary <- district_2018_summary %>%
  rename(District = sub) %>%
  mutate(District = tolower(District)) #lower case district names

# lower case districts
district_2023_wide <- district_2023_wide %>%
  mutate(District = tolower(District))

# Merge 2018 and 2023 district level results
district_competitiveness <- left_join(
  district_2018_summary,
  district_2023_wide,
  by = "District"
)

# Changes in competitiveness between 2018 and 2023
district_competitiveness <- district_competitiveness %>%
  mutate(
    change_largest_party_share = largest_party_share_2023 - largest_party_share_2018,
    change_margin = margin_2023 - margin_2018
  )

# Compute summary means
mean_row <- district_competitiveness %>%
  summarise(
    District = "Mean",
    `Largest Party Share 2018` = mean(largest_party_share_2018, na.rm = TRUE),
    `Largest Party Share 2023` = mean(largest_party_share_2023, na.rm = TRUE),
    `Change in Largest Share` = mean(change_largest_party_share, na.rm = TRUE),
    `Margin 2018` = mean(margin_2018, na.rm = TRUE),
    `Margin 2023` = mean(margin_2023, na.rm = TRUE),
    `Change in Margin` = mean(change_margin, na.rm = TRUE)
  )

# Output table 
district_competitiveness %>%
  dplyr::select(
    District,
    `Largest Party Share 2018` = largest_party_share_2018,
    `Largest Party Share 2023` = largest_party_share_2023,
    `Change in Largest Share` = change_largest_party_share,
    `Margin 2018` = margin_2018,
    `Margin 2023` = margin_2023,
    `Change in Margin` = change_margin
  ) %>%
  bind_rows(mean_row) %>%
  mutate(across(where(is.numeric), ~round(., 2))) %>%
  kable("latex", booktabs = TRUE, caption = "District-Level Competitiveness Before and After PR Reform (2018 vs 2023)",
        align = "lrrrrrr") %>%
  kable_styling(latex_options = c("hold_position"), font_size = 9)



# Appendix Section D -- file and data for Table D.1 uploaded separately using STATA - - see the README_APSR2025.rtf file for details.





#  --------------------------------------------------------------------------- ##
## Appendix Section E: Additional Field Experiment Results                      # 
#  --------------------------------------------------------------------------- ##

# Table E1: Summary Statistics --
selected_vars <- c("male", "respondent_educ_code", "respondent_age", "married", 
                   "respondent_children_code", "respondent_children_num", "mende", "krio", 
                   "temne", "kono", "fullah", "english", "discuss_politics_code", "registered",
                   "election_trust_2018_code", "would_vote", "would_encourage",  "treatment_status")
st(merged_data, vars = selected_vars, out = "latex") 

# Note that "discuss_politics_code" and "election_trust_2018_code" were both asked during baseline, and so reflect the baseline response summaries.
#`"election_trust_2018_code" measures the scaled mean response to the question asked during the baseline survey: 
# ``How strongly do you agree with the following statement? The 2018 election was free and fair. (1-4 scale)", with values closer to 4 indicating ``strong agree" and values closer to 1 indicating ``strongly disagree". 

# "discuss_politics_code" is an ordinal variable on a scale from 1-4, where 1 corresponds to the respondent answering that they never discuss politics with family and friends, to 4, which corresponds to the respondent answering that they very often discuss politics. 
# The discuss politics question was asked during baseline and endline both, so the one here reflects the baseline response summary which is pertinent when 
# checking for balance on pre-treatment covariates in Table E2. 
# In Tables E18 and E23, we use "final_discuss_politics_code" to reflect the endline response to how often the respondent discusses politics with friends and family.






# ------------------------------------------------------------------------------------------------------------------ 
# Table E2: Balance Table --

# Column 1 (without trust in election 2018)
balance<-lm(merged_data$treatment_status~merged_data$male+merged_data$noeducation + merged_data$party_IDAPC + merged_data$party_IDSLPP + merged_data$primary+merged_data$juniorsecondary+merged_data$highschool+merged_data$respondent_age+merged_data$married
            +merged_data$respondent_children_num+merged_data$mende+merged_data$krio+merged_data$discuss_politics_code)
summary(balance)  # F-stat is 1.420
# Column 2 (with trust in 2018)
balance2<-lm(merged_data$treatment_status~merged_data$male+merged_data$noeducation + merged_data$party_IDAPC + merged_data$party_IDSLPP + merged_data$primary+merged_data$juniorsecondary+merged_data$highschool+merged_data$respondent_age+merged_data$married
            +merged_data$respondent_children_num+merged_data$mende+merged_data$krio+merged_data$discuss_politics_code+merged_data$election_trust_2018_code)
summary(balance2)  # F-stat is 1.424
stargazer(balance, balance2, title="Balance Table", align=TRUE, type="text") 





# ------------------------------------------------------------------------------------------------------------------ 
# Table E3: Lack of Differential Attrition --

# Differential attrition by treatment status
# "attrited endline" is an indicator for respondents from the baseline survey that did not participate in the follow-up survey 
# 1 = attrited, 0 = partcipated in both baseline and endline
attrition_model <- lm(attrited_endline ~ treatment_status, data=baseline_data) 
summary(attrition_model)
stargazer(attrition_model, title = "Lack of Differential Attrition", align = TRUE, type = "text")





# ------------------------------------------------------------------------------------------------------------------ 
# Table E4: Null Effects on General Political Knowledge --

# Correct knowledge of candidate list process (column 1)
merged_data$knows_mplist<-ifelse(merged_data$mp_selection_knowledge=="It is the political parties that decide who the MP candidates will be.",1,0) 
knowledge_mplist<-lm(merged_data$knows_mplist~treatment_status+married+respondent_children_num,data=merged_data)

# Create a continuous variable for the count of correct answers to question about which positions will be voted for on the ballot
merged_data$knows_positions <- merged_data$positions_knowledge_president +
  merged_data$positions_knowledge_mp +
  merged_data$positions_knowledge_councilor +
  merged_data$positions_knowledge_district_chair +
  merged_data$positions_knowledge__mayor

# Correct knowledge of positions on ballot (column 2)
knowledge_positions<-lm(merged_data$knows_positions~treatment_status+married+respondent_children_num,data=merged_data)

# Create a variable for the knowledge question about women under PR
merged_data$knowspr_women<-ifelse(merged_data$knowledge_women_system=="Agree with Statement 1",1,0) 

# Correct knowledge of women's representation (column 3)
knowledge_prwomen<-lm(merged_data$knowspr_women~treatment_status+married+respondent_children_num,data=merged_data)

stargazer(knowledge_mplist, knowledge_positions, knowledge_prwomen, 
          title="Null Results on General Political Knowledge", align=TRUE,  type = "text")





# ------------------------------------------------------------------------------------------------------------------ 
# Table E5: Null Effects on General Knowledge Index --

# Variables in index: knowspr_mp, knows_mplist, knowspr_pres, knowspr_women, knows_position

# Standardize each component (compute z-scores)
merged_data <- merged_data %>%
  mutate(
    z_knowspr_mp = scale(knowspr_mp)[,1],
    z_knows_mplist = scale(knows_mplist)[,1],
    z_knowspr_pres = scale(knowspr_pres)[,1],
    z_knowspr_women = scale(knowspr_women)[,1],
    z_knows_positions = scale(knows_positions)[,1]
  )

# Create the knowledge index as the average of z-scores
merged_data$knowledge_index <- rowMeans(merged_data[, c("z_knowspr_mp", "z_knows_mplist", "z_knowspr_pres", "z_knowspr_women", "z_knows_positions")], na.rm = TRUE)

# Regression using knowledge index
knowledge_index_model <- lm(knowledge_index ~ treatment_status + married + respondent_children_num, data = merged_data)
stargazer(knowledge_index_model, title = "Null Effects on Knowledge Index", align = TRUE, type = "text")




# ------------------------------------------------------------------------------------------------------------------ 
# Table E6: Predictors of Knowledge of MP Ballot Rules (Control Group Only) --

# Control subset 
ctrl_df <- merged_data %>% filter(treatment_status == 0)

# Shortlist potential demographic/geographic predictors of knowledge of ballot in the control
# Model (1): Demographics only 
m1_ctrl_knowledge <- glm(
  knowspr_mp ~ male + married + college_educ + low_education +
    respondent_age + respondent_children_num +
    mende + krio + temne + kono + fullah,   # language indicators for four biggest language groups (baseline = all other languages)
  data = ctrl_df,
  family = binomial()
)

#  Model (2): Demographics + province
m2_ctrl_knowledge <- glm(
  knowspr_mp ~ male + married + college_educ + low_education +
    respondent_age + respondent_children_num +
    mende + krio + temne + kono + fullah + # language indicators for four biggest language groups (baseline = all other languages)
    province_factor,   # province FE, reference category = eastern province
  data = ctrl_df,
  family = binomial()
)

# Model (3): Demographics + district
ctrl_df$district_factor <- relevel(factor(ctrl_df$district.y), ref = "kenema") # set kenema as the reference category for model 3 which includes districts
m3_ctrl_knowledge <- glm(
  knowspr_mp ~ male + married + college_educ + low_education +
    respondent_age + respondent_children_num +
    mende + krio + temne + kono + fullah +
    district_factor,
  data = ctrl_df,
  family = binomial()
)

# Compute clustered SEs for all models
cov_m1 <- vcovCL(m1_ctrl_knowledge, cluster = ctrl_df$province_factor)
cov_m2 <- vcovCL(m2_ctrl_knowledge, cluster = ctrl_df$province_factor)
cov_m3 <- vcovCL(m3_ctrl_knowledge, cluster = ctrl_df$district_factor)

se_m1 <- sqrt(diag(cov_m1))
se_m2 <- sqrt(diag(cov_m2))
se_m3 <- sqrt(diag(cov_m3))

# Stargazer table with clustered SEs
stargazer::stargazer(
  m1_ctrl_knowledge, m2_ctrl_knowledge, m3_ctrl_knowledge,
  se = list(se_m1, se_m2, se_m3),
  title = "Predictors of Knowledge of MP Ballot Rules (Control Group Only)",
  dep.var.labels = "Knows MP ballot elects parties",
  column.labels = c("Demographics only", "+ Province", "+ District"),
  covariate.labels = c(
    "Male", "Married", "College educated", "Low education",
    "Age", "Number of children",
    "Mende", "Krio", "Temne", "Kono", "Fullah",
    "North-West Province", "Northern Province",
    "Southern Province", "Western Rural", "Western Urban",
    # district FE labels
    "Bo", "Bombali", "Bonthe", "Falaba", "Kailahun", "Kambia",
    "Karene", "Koinadugu", "Kono", "Moyamba", "Port Loko",
    "Pujehun", "Tonkolili", "Western Rural District", "Western Urban District"
  ),
  keep.stat = c("n","ll","aic"),
  intercept.bottom = TRUE,
  no.space = TRUE,
  digits = 3,
  star.cutoffs = c(0.1, 0.05, 0.01),
  header = FALSE,
  notes = "",
  notes.append = FALSE,
  type = "text"
)




# ------------------------------------------------------------------------------------------------------------------ 
# Table E7: Mediation of PR Knowledge on Support for Particularistic Appeals -- 

# Note:this is a simulation-based approach, so the numbers in Table E7 will not match perfectly each time, but will be very close. Set seed as below.
set.seed(9999)

# Subsetting to only non-missing data
data_appeal <- na.omit(merged_data[, c("liked_targeted_appeal", "knowspr_mp", 
                                       "treatment_status", "party_ID", "married", 
                                       "respondent_children_num")])  #733 obs

# Mediator model (knowledge)
model_m <- lm(knowspr_mp ~ treatment_status + married + respondent_children_num, data = data_appeal)

# Outcome model (approval of particularistic appeals)
model_y <- lm(liked_targeted_appeal ~ treatment_status + knowspr_mp + married + respondent_children_num, data = data_appeal)

mediation_appeal <- mediate(model.m = model_m,
                            model.y = model_y,
                            treat = "treatment_status",
                            mediator = "knowspr_mp",
                            sims = 1000)
# View results
summary(mediation_appeal) 

# Convert mediation output to summary table for outputting
summ_to_df <- function(med_obj) {
  s <- summary(med_obj)
  data.frame(
    Effect = c("ACME (Indirect Effect)",
               "ADE (Direct Effect)",
               "Total Effect",
               "Proportion Mediated"),
    Estimate = c(s$d0, s$z0, s$tau.coef, s$n0),
    `95% CI Lower` = c(s$d0.ci[1], s$z0.ci[1], s$tau.ci[1], s$n0.ci[1]),
    `95% CI Upper` = c(s$d0.ci[2], s$z0.ci[2], s$tau.ci[2], s$n0.ci[2]),
    `p-value` = c(s$d0.p, s$z0.p, s$tau.p, s$n0.p)
  )
}

# Create tables for outputting mediation analysis
tab_med_appeal <- summ_to_df(mediation_appeal)

stargazer(
  tab_med_appeal, summary = FALSE, type = "text",
  title = "Mediation of PR Knowledge on Support for Particularistic Appeals",
  digits = 3, rownames = FALSE,
  notes = "Quasi-Bayesian 95\\% confidence intervals based on 1,000 simulations. Full sample included.",
  notes.align = "l"
)




# ------------------------------------------------------------------------------------------------------------------ 
# Table E8: Mediation of Knowledge on Support for Particularistic Appeals (Excluding Western Rural) -- 

# Note: this is a simulation-based approach, so the numbers in Table E8 will not match perfectly each time, but will be very close. Set seed as below.
set.seed(9999)

# Subsetting to non-Western Rural data
data_outside_WR <- merged_data %>%
  filter(western_rural == 0)

# Mediator model (knowledge)
M_appeal_outWR <- lm(knowspr_mp ~ treatment_status + married + respondent_children_num,
                     data =  data_outside_WR)

# Outcome model (approval of particularistic appeals)
Y_appeal_outWR <- lm(liked_targeted_appeal ~ treatment_status + knowspr_mp +
                       married + respondent_children_num,
                     data =  data_outside_WR)

med_appeal_outWR <- mediate(model.m = M_appeal_outWR,
                            model.y = Y_appeal_outWR,
                            treat   = "treatment_status",
                            mediator= "knowspr_mp",
                            sims    = 1000)
# View summary
print(summary(med_appeal_outWR))

# Convert to table for outputting
tab_med_appeal_outWR <- summ_to_df(med_appeal_outWR)

stargazer(
  tab_med_appeal_outWR, summary = FALSE, type = "text",
  title = "Mediation of Knowledge on Support for Particularistic Appeals (Excluding Western Rural)",
  digits = 3, rownames = FALSE,
  notes = "Quasi-Bayesian 95\\% confidence intervals based on 1,000 simulations. Estimates exclude Western Rural respondents, where knowledge about MP ballots using PR was higher than the rest of the country.",
  notes.align = "l"
) 




# ------------------------------------------------------------------------------------------------------------------ 
# Table E9: Treatment Effects on Knowledge of Electoral Systems, Full Results -- 

  # Note: the code for E9 is exactly the same as for Table 1. In Table 1, only the main coefficients of interest were displayed. 
  # The coefficients for covariates were not displayed in the main text for stylistic reasons.


# ------------------------------------------------------------------------------------------------------------------ 
# Table E10: Treatment Effects on Approval of Different Campaign Appeals, Full Results  -- 

  # Note: the code for E10 is exactly  the same as for Table 3. In Table 3, only the main coefficients of interest were displayed. 
  # The coefficients for covariates were not displayed in the main text for stylistic reasons.


# ------------------------------------------------------------------------------------------------------------------ 
# Table E11: Treatment Effects on Political Participation, Full Results -- 

  # Note: the code for E11 is exactly  the same as for Table 2. In Table 2, only the main coefficients of interest were displayed. 
  # The coefficients for covariates were not displayed in the main text for stylistic reasons.


# ------------------------------------------------------------------------------------------------------------------ 
# Table E12: Effects of Treatment on Trust in Elections, Full Results -- 

  # Note: the code for E12 is exactly the same as for Table 4. In Table 4, only the main coefficients of interest were displayed. 
  # The coefficients for covariates were not displayed in the main text for stylistic reasons.


# ------------------------------------------------------------------------------------------------------------------ 
# Table E13: Treatment Effects on Knowledge of Electoral Systems, Without Covariates -- 

# Knows MP elected through PR (column 1)
knowledge_mppr_nocov<-lm(merged_data$knowspr_mp~treatment_status,data=merged_data)

# Knows President Elected through FPTP (column 2)
knowledge_presfptp_nocov<-lm(merged_data$knowspr_pres~treatment_status,data=merged_data)

# Accurate Answers about Women's Representation (column 3)
knowledge_prwomen_nocov<-lm(merged_data$knowspr_women~treatment_status,data=merged_data)

stargazer(knowledge_mppr_nocov, knowledge_presfptp_nocov, knowledge_prwomen_nocov, 
          title="Treatment Effects on Knowledge of Electoral Systems, Without Covariates", align=TRUE,  type = "text")




# ------------------------------------------------------------------------------------------------------------------ 
# Table E14: Treatment Effects on Approval of Different Campaign Appeals, Without Covariates -- 

# Strong approval of universal appeal (column 1)
universal_appeal_reg_nocov <- lm(liked_universal_appeal ~ treatment_status + 
                             party_ID + treatment_status:party_ID, data = merged_data)

# Strong approval of particularistic appeal (column 2)
targeted_appeal_reg_nocov <- lm(liked_targeted_appeal ~ treatment_status + 
                            party_ID + treatment_status:party_ID, data = merged_data)

# Strong approval of leader quality appeal (column 3)
leader_appeal_reg_nocov <- lm(liked_leader_appeal ~ treatment_status + 
                          party_ID + treatment_status:party_ID, data = merged_data)

stargazer(universal_appeal_reg_nocov, targeted_appeal_reg_nocov, leader_appeal_reg_nocov, 
          title = "Treatment Effects on Approval of Different Campaign Appeals, Without Covariates", align = TRUE,  type = "text")




# ------------------------------------------------------------------------------------------------------------------ 
# Table E15: Treatment Effects on Participation by Gender, Without Covariates --

# Would vote (column 1)
turnout_gender_nocov<-lm(merged_data$would_vote~treatment_status*male,data=merged_data)

# Vote wait time (column 2)
wait_hours_gender_nocov<-lm(merged_data$vote_wait_time~treatment_status*male,data=merged_data)

# Would volunteer (column 3)
volunteer_gender_nocov<-lm(merged_data$would_volunteer~treatment_status*male,data=merged_data)

# Encourage others (column 4)
encourage_gender_nocov<-lm(merged_data$would_encourage~treatment_status*male,data=merged_data)

# Store models in a list and output
participation_gender_nocov_list <- list(turnout_gender_nocov,wait_hours_gender_nocov, volunteer_gender_nocov, encourage_gender_nocov)
stargazer(participation_gender_nocov_list,
          title="Treatment Effects on Participation by Gender, Without Covariates", 
          align=TRUE,  type = "text")



# ------------------------------------------------------------------------------------------------------------------ 
# Table E16: Effects of Treatment on Trust in Elections, Without Covariates --

# Trust in Free and Fair Election (Column 1)
election_hightrust_treat_regression_nocov <- lm(election_hightrust_endline ~ trust_group_indicator*treatment_status, data=merged_data)

# Trust in Vote Counting Process (Column 2)
trustcount_treat_regression_nocov <- lm(trust_count ~ trust_group_indicator*treatment_status, data=merged_data)

# Trust in Peaceful Election (Column 3)
trustpeace_treat_regression_nocov <- lm(trust_peace ~ trust_group_indicator*treatment_status, data=merged_data)

# Store models in a list and output
trust_order_models_nocov <- list(election_hightrust_treat_regression_nocov, 
                           trustcount_treat_regression_nocov, 
                           trustpeace_treat_regression_nocov)
stargazer(trust_order_models_nocov, 
          title="Effects of Treatment on Trust in Elections, Without Covariates", 
          align=TRUE,  type = "text")




# ------------------------------------------------------------------------------------------------------------------ 
# Table E17: Treatment Effects on Participation Outcomes by Partisanship -- 

# Would vote (column 1)
vote_interaction_party <- lm(would_vote ~ party_ID * treatment_status + respondent_children_num + married, data=merged_data)

# Vote wait time (column 2)
wait_time_interaction_party <- lm(vote_wait_time ~ party_ID * treatment_status + respondent_children_num + married, data=merged_data)

# Would volunteer (column 3)
volunteer_interaction_party <- lm(would_volunteer ~ party_ID * treatment_status + respondent_children_num + married, data=merged_data)

# Would encourage others (column 4)
encourage_interaction_party <- lm(would_encourage ~ party_ID * treatment_status + respondent_children_num + married, data=merged_data)

# Store models in a list and output
participation_party_list1 <- list(vote_interaction_party, wait_time_interaction_party, volunteer_interaction_party, encourage_interaction_party)
stargazer(participation_party_list1, 
          title="Treatment Effects on Participation Outcomes by Partisanship", 
          align=TRUE,  type = "text")




# ------------------------------------------------------------------------------------------------------------------ 
# Table E18: Treatment Effects on Participation Outcomes by Partisanship -- 

# Discuss politics (column 1)
discuss_politics_interaction_party <- lm(final_discuss_politics_code ~ party_ID * treatment_status + respondent_children_num + married, data=merged_data)

# Attended a rally (column 2)
rally_present_interaction_party <- lm(final_rally_present ~ party_ID * treatment_status + respondent_children_num + married, data=merged_data)

# Would register others (column 3)
merged_data$would_registeroths<-ifelse(merged_data$vote_register_others=="Yes, I would do this",1,0) 
registeroths_interaction_party <- lm(would_registeroths ~ party_ID * treatment_status + respondent_children_num + married, data=merged_data)

# Store models in a list and output
participation_party_list2 <- list(discuss_politics_interaction_party, rally_present_interaction_party, registeroths_interaction_party)
stargazer(participation_party_list2, 
          title="Participation Outcomes by Regional Partisanship and Treatment", 
          align=TRUE,  type = "text")




# ------------------------------------------------------------------------------------------------------------------ 
# Table E19: Trust Outcomes by Partisanship and Treatment -- 

# Trust in free and fair election (column 1)
trust_election_interaction_party <- lm(election_hightrust_endline ~ party_ID * treatment_status + respondent_children_num + married, data=merged_data)
summary(trust_election_interaction_party)

# Trust in counting process (column 2)
trust_count_interaction_party <- lm(trust_count ~ party_ID * treatment_status + respondent_children_num + married, data=merged_data)
summary(trust_count_interaction_party)

# Trust in peaceful election (column 3)
trust_peace_interaction_party <- lm(trust_peace ~ party_ID * treatment_status + respondent_children_num + married, data=merged_data)
summary(trust_peace_interaction_party)

# Store models in a list and output
trust_interactions_party_list <- list(trust_election_interaction_party, trust_count_interaction_party, trust_peace_interaction_party)
stargazer(trust_interactions_party_list, 
          title = "Trust Outcomes by Partisanship and Treatment", 
          align = TRUE,  type = "text")




# ------------------------------------------------------------------------------------------------------------------ 
# Table E20: Effects on Participation by Third-Party/Independent Disadvantage Districts under PR and Gender -- 

# Regression models for participation outcomes with third-party/independent disadvantage as a moderator

# Would vote (column 1)
turnout_disadvantage_gender <- lm(would_vote ~ treatment_status * third_party_or_independent_disadvantaged + respondent_children_num + married, data = merged_data)

# Vote wait time (column 2)
wait_hours_disadvantage_gender <- lm(vote_wait_time ~ treatment_status * third_party_or_independent_disadvantaged * female + respondent_children_num + married, data = merged_data)

# Would volunteer (column 3)
volunteer_disadvantage_gender <- lm(would_volunteer ~ treatment_status * third_party_or_independent_disadvantaged * female + respondent_children_num + married, data = merged_data)

# Encourage others (column 4)
encourage_disadvantage_gender <- lm(would_encourage ~ treatment_status * third_party_or_independent_disadvantaged * female + respondent_children_num + married, data = merged_data)

# Combine participation models into a list
participation_disadvantage_models <- list(turnout_disadvantage_gender, wait_hours_disadvantage_gender, volunteer_disadvantage_gender, encourage_disadvantage_gender)

# Output table
stargazer(participation_disadvantage_models, 
          title = "Effects on Participation by Third-Party/Independent Disadvantage under PR and Gender", 
          align = TRUE,  type = "text")





# ------------------------------------------------------------------------------------------------------------------ 
# Table E21: Effects on Trust Moderated by Third-Party/Independent Disadvantage under PR -- 

# Trust in Free and Fair Election (Column 1)
election_hightrust_disadvantage <- lm(election_hightrust_endline ~ treatment_status * third_party_or_independent_disadvantaged + respondent_children_num + married, data = merged_data)

# Trust in Vote Counting Process (Column 2)
trustcount_disadvantage <- lm(trust_count ~ treatment_status * third_party_or_independent_disadvantaged + respondent_children_num + married, data = merged_data)

# Trust in Peaceful Election (Column 3)
trustpeace_disadvantage <- lm(trust_peace ~ treatment_status * third_party_or_independent_disadvantaged + respondent_children_num + married, data = merged_data)

# Combine trust models into a list
trust_disadvantage_models <- list(election_hightrust_disadvantage, trustcount_disadvantage, trustpeace_disadvantage)

# Output table
stargazer(trust_disadvantage_models, 
          title = "Effects on Trust Moderated by Third-Party/Independent Disadvantage", 
          align = TRUE,  type = "text")




# ------------------------------------------------------------------------------------------------------------------ 
# Table E22:  Effects on Trust Moderated by 2018 Reminders and Third-Party/Independent Disadvantage -- 

# Regression models for trust outcomes with third-party/independent disadvantage and trust group indicator (being reminder of 2018 election first) as a moderator

# Trust in Free and Fair Election (Column 1)
election_hightrust_disadvantage_ordered <- lm(election_hightrust_endline ~ treatment_status * trust_group_indicator * third_party_or_independent_disadvantaged + respondent_children_num + married, data = merged_data)

# Trust in Vote Counting Process (Column 2)
trustcount_disadvantage_ordered <- lm(trust_count ~ treatment_status * trust_group_indicator * third_party_or_independent_disadvantaged + respondent_children_num + married, data = merged_data)

# Trust in Peaceful Election (Column 3)
trustpeace_disadvantage_ordered <- lm(trust_peace ~ treatment_status * trust_group_indicator * third_party_or_independent_disadvantaged + respondent_children_num + married, data = merged_data)

# Combine trust models into a list
trust_disadvantage_models_ordered <- list(election_hightrust_disadvantage_ordered, trustcount_disadvantage_ordered, trustpeace_disadvantage_ordered)

# Stargazer output for trust models
stargazer(trust_disadvantage_models_ordered, 
          title = "Effects on Trust Moderated by 2018 Reminders and Third-Party/Independent Disadvantage", 
          align = TRUE,  type = "text")





# ------------------------------------------------------------------------------------------------------------------ 
# Table E23: Differential Attrition on Sensitive Questions -- 

# Creating indicators for attrition on each sensitive variable
merged_data$attrited_trust_election <- ifelse(is.na(merged_data$final_trust_election), 1, 0)
merged_data$attrited_rally_present <- ifelse(is.na(merged_data$final_rally_present), 1, 0)
merged_data$attrited_discuss_politics <- ifelse(is.na(merged_data$final_discuss_politics_code), 1, 0)

# Analyzing differential attrition on sensitive questions by treatment status

# Free and fair elections (column 1)
trust_election_attrition <- lm(attrited_trust_election ~ treatment_status, data=merged_data)

# Rally attendance (column 2)
rally_present_attrition <- lm(attrited_rally_present ~ treatment_status, data=merged_data)

# Discuss politics (column 3)
discuss_politics_attrition <- lm(attrited_discuss_politics ~ treatment_status, data=merged_data)

stargazer(trust_election_attrition, rally_present_attrition, discuss_politics_attrition, 
          title = "Differential Attrition on Sensitive Questions", 
          align = TRUE,  type = "text") 




# ------------------------------------------------------------------------------------------------------------------ 
# Table E24: Identifying SLPP Campaign Issues -- 

# Education policy and protecting women and girls were top SLPP campaign issues

# Education (column 1)
merged_data$educ_issue_correct<-ifelse(merged_data$party_educ=="Sierra Leone People Party (SLPP)",1,0)
educ_issue_correct<-lm(educ_issue_correct~treatment_status+married+respondent_children_num,data=merged_data)

# Gender (column 2)
merged_data$gender_issue_correct<-ifelse(merged_data$party_women=="Sierra Leone People Party (SLPP)",1,0)
gender_issue_correct<-lm(gender_issue_correct~treatment_status+married+respondent_children_num,data=merged_data)

stargazer(educ_issue_correct, gender_issue_correct, title="Identifying SLPP Campaign Issues", 
          align=TRUE,  type = "text")




# ------------------------------------------------------------------------------------------------------------------ 
# Table E25: Effects on Identifying SLPP Campaign Issues (Moderated by Party Identification) -- 

# Education policy and protecting women and girls were top SLPP campaign issues

# Education (column 1)
educ_issue_correct_2 <- lm(educ_issue_correct ~ treatment_status * party_ID + married + respondent_children_num, data = merged_data)

# Gender (column 2)
gender_issue_correct_2 <- lm(gender_issue_correct ~ treatment_status * party_ID + married + respondent_children_num, data = merged_data)

stargazer(educ_issue_correct_2, gender_issue_correct_2, 
          title = "Effects on Identifying SLPP Campaign Issues", align = TRUE,  type = "text")




# ------------------------------------------------------------------------------------------------------------------ 
# Table E26: Effects on Identifying APC Campaign Issues -- 

# The economy and healthcare policy were APC campaign issues

# The Economy (column 1)
merged_data$econ_issue_correct<-ifelse(merged_data$party_econ=="All Peoples  Congress (APC)",1,0)
econ_issue_correct<-lm(econ_issue_correct~treatment_status+married+respondent_children_num,data=merged_data)

# Healthcare (column 2)
merged_data$health_issue_correct<-ifelse(merged_data$party_health=="All Peoples  Congress (APC)",1,0)
health_issue_correct<-lm(health_issue_correct~treatment_status+married+respondent_children_num,data=merged_data)

stargazer(econ_issue_correct, health_issue_correct, 
          title="Effects on Identifying APC Campaign Issues", align=TRUE,  type = "text")




# ------------------------------------------------------------------------------------------------------------------ 
# Table E27: Effects on Identifying APC Campaign Issues ((Moderated by Party Identification) -- 

# The economy and healthcare policy were APC campaign issues

# The Economy (column 1)
econ_issue_correct_2 <- lm(econ_issue_correct ~ treatment_status * party_ID + married + respondent_children_num, data = merged_data)

# Healthcare (column 2)
health_issue_correct_2 <- lm(health_issue_correct ~ treatment_status * party_ID + married + respondent_children_num, data = merged_data)

stargazer(econ_issue_correct_2, health_issue_correct_2, 
          title = "Effects on Identifying APC Campaign Issues", align = TRUE,  type = "text")




# ------------------------------------------------------------------------------------------------------------------ 
# Table E28: Treatment Effects on Socially Desirable Responses --

# Ethnic vote MP (column 1)
vote_basedonethnicity<-lm(merged_data$vote_factor_mp_ethnic~treatment_status+respondent_children_num+married,data=merged_data)

# Ethnic vote president (column 2)
vote_pres_ethnicity<-lm(merged_data$vote_factor_president_ethnic~treatment_status+respondent_children_num+married,data=merged_data)

# No good candidates (column 3)
no_good_candidates_model <- lm(concerns_elections_candidates ~ treatment_status+respondent_children_num+married, data = merged_data)

# Store models in a list and output table
experimenter_demand_list <- list(vote_basedonethnicity, vote_pres_ethnicity, no_good_candidates_model)
stargazer(experimenter_demand_list,
          title = "Treatment Effects on Socially Desirable Responses", 
          align = TRUE,  type = "text",
          column.labels = c("Ethnic vote MP", "Ethnic vote President", "No Good Candidates"))





# ------------------------------------------------------------------------------------------------------------------ 
# Table E29: Treatment Effects on Social Desirable Responses, Full Results -- 

  # Note: This is the same table code as for Table E28, just with the covariates 
  # for no. of children and marital status displayed in the output.   


# ------------------------------------------------------------------------------------------------------------------ 
# Table E30: Treatment Effects on Socially Desirable Responses, Without Covariates -- 

# Ethnic vote MP (column 1)
vote_basedonethnicity_nocov<-lm(merged_data$vote_factor_mp_ethnic~treatment_status,data=merged_data)

# Ethnic vote president (column 2)
vote_pres_ethnicity_nocov<-lm(merged_data$vote_factor_president_ethnic~treatment_status,data=merged_data)

# No good candidates (column 3)
no_good_candidates_model_nocov <- lm(concerns_elections_candidates ~ treatment_status, data = merged_data)

# Store models in a list and output table
experimenter_demand_list_nocov <- list(vote_basedonethnicity_nocov, vote_pres_ethnicity_nocov, no_good_candidates_model_nocov)
stargazer(experimenter_demand_list_nocov,
          title = "Treatment Effects on Socially Desirable Responses", 
          align = TRUE,  type = "text",
          column.labels = c("Ethnic vote MP", "Ethnic vote President", "No Good Candidates"))





# ------------------------------------------------------------------------------------------------------------------ 
# Table E31: Treatment Effects on Trust Index --

# Simple average of variables to create trust index: election_hightrust_endline, trust_count, trust_peace
merged_data$trust_index <- rowMeans(
  merged_data[, c("election_hightrust_endline", "trust_count", "trust_peace")],
  na.rm = TRUE
)

# Regress trust index
trust_index_regression <- lm(trust_index ~ trust_group_indicator * treatment_status + respondent_children_num + married,
                             data = merged_data)

stargazer(trust_index_regression, title = "Treatment Effects on Trust Index", align = TRUE,  type = "text")





# ------------------------------------------------------------------------------------------------------------------ 
# Table E32: Treatment Effects on Approval of Appeals Moderated by Ethnic Diversity --

# Strong approval of universal campaign appeal (Column 1)
universal_appeal_elf_diff_reg <- lm(liked_universal_appeal ~ treatment_status * EFDI.y + party_ID 
                                    + respondent_children_num + married, data = merged_data)

# Strong approval of particularistic appeal (Column 2)
targeted_appeal_elf_diff_reg <- lm(liked_targeted_appeal ~ treatment_status * EFDI.y + party_ID
                                   + respondent_children_num + married, data = merged_data)
    
# Strong approval of leader-quality appeal (Column 3)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              
leader_appeal_elf_diff_reg <- lm(liked_leader_appeal ~ treatment_status * EFDI.y + party_ID
                                 + respondent_children_num + married, data = merged_data)

# Clustering standard errors at chiefdom level
clustered_universal_elf_diff <- coeftest(universal_appeal_elf_diff_reg, vcov = vcovCL(universal_appeal_elf_diff_reg, type = "HC1", cluster = ~chiefdom, data = merged_data))
clustered_targeted_elf_diff <- coeftest(targeted_appeal_elf_diff_reg, vcov = vcovCL(targeted_appeal_elf_diff_reg, type = "HC1", cluster = ~chiefdom, data = merged_data))
clustered_leader_elf_diff <- coeftest(leader_appeal_elf_diff_reg, vcov = vcovCL(leader_appeal_elf_diff_reg, type = "HC1", cluster = ~chiefdom, data = merged_data))

# Create a list to store models
clustered_elf_diff_models <- list(
  clustered_universal_elf_diff,
  clustered_targeted_elf_diff,
  clustered_leader_elf_diff 
)

# Output table
stargazer(clustered_elf_diff_models,
          title = "Treatment Effects on Approval of Appeals Interacted with Ethnic Fractionalization",
          align = TRUE, type = "text")




# ------------------------------------------------------------------------------------------------------------------ 
# Table E33: False Discovery Rate (Benjamini–Hochberg) within Knowledge Family -- 

# List of knowledge models
models_knowledge_fdr <- list(
  "MP elected via PR"        = knowledge_mppr,
  "Candidate-list process"   = knowledge_mplist
)

# Function to extract model parameters
extract_itt <- function(m, term = "treatment_status"){
  s <- coef(summary(m))
  c(
    Estimate = s[term, "Estimate"],
    StdError = s[term, "Std. Error"],
    P        = s[term, "Pr(>|t|)"],
    N        = nobs(m)
  )
}

# Build results dataframe
K2 <- do.call(rbind, lapply(models_knowledge_fdr, extract_itt))
K2 <- as.data.frame(K2)
K2$Outcome <- rownames(K2); rownames(K2) <- NULL

# FDR corrections within family of knowledge outcomes
K2$Q_BH    <- p.adjust(K2$P, method = "BH")
K2$`q<.05` <- ifelse(K2$Q_BH < .05, "Yes", "No")
K2$`q<.10` <- ifelse(K2$Q_BH < .10, "Yes", "No")
K2$Estimate <- round(K2$Estimate, 3)
K2$StdError <- round(K2$StdError, 3)
K2$P        <- signif(K2$P, 3)
K2$Q_BH     <- signif(K2$Q_BH, 3)
K2$N        <- as.integer(K2$N)
K2 <- K2[, c("Outcome","Estimate","StdError","P","Q_BH","N")]

# Output table
stargazer::stargazer(
  K2, summary = FALSE, rownames = FALSE,
  title = "False Discovery Rate (Benjamini–Hochberg) within Knowledge Family",
  digits = 3,
  notes = c(
    "Family includes only knowledge outcomes expected to move by treatment: MP elected via PR and candidate-list process.",
    "Entries are ITT effects of treatment; q-values are Benjamini–Hochberg FDR-adjusted within this family.",
    "Covariates include marital status and number of children."
  ),
  notes.append = FALSE, 
  type = "text"
)




# ------------------------------------------------------------------------------------------------------------------ 
# Table E34: False Discovery Rate Adjustment (BH) within Intent to Participate Family -- 

# List of intent to participate models (same models as created for Table 3)
models_participation <- list(
  "Would vote"       = turnout_gender,
  "Vote wait time"   = wait_hours_gender,
  "Would volunteer"  = volunteer_gender,
  "Encourage others" = encourage_gender
)

extract_itt <- function(m, term = "treatment_status") {
  s <- coef(summary(m))
  est <- s[term, "Estimate"]
  se  <- s[term, "Std. Error"]
  p   <- s[term, "Pr(>|t|)"]
  n   <- nobs(m)
  c(Estimate = est, StdError = se, P = p, N = n)
}

# Extract both main treatment and interaction terms
extract_terms <- function(m, terms) {
  s <- coef(summary(m))
  out <- data.frame(
    Outcome  = terms,
    Estimate = s[terms, "Estimate"],
    StdError = s[terms, "Std. Error"],
    P        = s[terms, "Pr(>|t|)"],
    N        = nobs(m)
  )
  out
}

# Existing main effects
P_main <- do.call(rbind, lapply(models_participation, extract_itt))
P_main <- as.data.frame(P_main); P_main$Outcome <- rownames(P_main); rownames(P_main) <- NULL

# Add the interaction term from wait_hours_gender
P_int <- extract_terms(wait_hours_gender, "treatment_status:male")
P_int$Outcome <- "Vote wait time × Male"

# Combine and apply BH correction
P_all <- rbind(P_main, P_int)
P_all$Q_BH  <- p.adjust(P_all$P, method = "BH")
P_all$`q<.05` <- ifelse(P_all$Q_BH < .05, "Yes", "No")
P_all$`q<.10` <- ifelse(P_all$Q_BH < .10, "Yes", "No")

P_all$Estimate <- round(P_all$Estimate, 3)
P_all$StdError <- round(P_all$StdError, 3)
P_all$P        <- signif(P_all$P, 3)
P_all$Q_BH     <- signif(P_all$Q_BH, 3)
P_all$N        <- as.integer(P_all$N)
P_all <- P_all[, c("Outcome","Estimate","StdError","P","Q_BH","N")]

# Output table
stargazer::stargazer(
  P_all, summary = FALSE, rownames = FALSE,
  title = "False Discovery Rate Adjustment (BH) within Intent to Participate Family",
  digits = 3,
  notes = c(
    "Entries include main treatment effects and gender interaction for vote-wait time.",
    "q-values are Benjamini–Hochberg FDR-adjusted within the intent to participate family.",
    "Covariates include marital status and number of children."
  ),
  notes.append = FALSE, 
  type = "text"
)





# ------------------------------------------------------------------------------------------------------------------ 
# Table E35: False Discovery Rate Adjustment (BH) within Trust Family -- 

# List of trust models (same models as created for Table 4)
models_trust <- list(
  "Trust free and fair election" = election_hightrust_treat_regression,
  "Trust vote counting"        = trustcount_treat_regression,
  "Trust peaceful election"    = trustpeace_treat_regression
)

# Extract both main and interaction effects
extract_terms <- function(m, terms) {
  s <- coef(summary(m))
  out <- data.frame(
    Term     = terms,
    Estimate = s[terms, "Estimate"],
    StdError = s[terms, "Std. Error"],
    P        = s[terms, "Pr(>|t|)"],
    N        = nobs(m)
  )
  out
}

T_main <- do.call(rbind, lapply(models_trust, extract_itt))
T_main <- as.data.frame(T_main); T_main$Outcome <- rownames(T_main); rownames(T_main) <- NULL

# Extract interaction terms from the trust model
T_int <- do.call(rbind, lapply(models_trust, extract_terms, "trust_group_indicator:treatment_status"))
T_int$Outcome <- paste0(rownames(T_int), " (interaction)") 
T_int$Term <- NULL; rownames(T_int) <- NULL

# Combine and correct the p-vals for main treatment term and the interaction
Tr_all <- rbind(T_main, T_int)

# Apply FDR correction
Tr_all$Q_BH <- p.adjust(Tr_all$P, method = "BH")
Tr_all$`q<.05` <- ifelse(Tr_all$Q_BH < .05, "Yes", "No")
Tr_all$`q<.10` <- ifelse(Tr_all$Q_BH < .10, "Yes", "No")

# Round and reorder columns
Tr_all$Estimate <- round(Tr_all$Estimate, 3)
Tr_all$StdError <- round(Tr_all$StdError, 3)
Tr_all$P        <- signif(Tr_all$P, 3)
Tr_all$Q_BH     <- signif(Tr_all$Q_BH, 3)
Tr_all$N        <- as.integer(Tr_all$N)

Tr_all <- Tr_all[, c("Outcome","Estimate","StdError","P","Q_BH","N")]

# Output table
stargazer::stargazer(
  Tr_all, summary = FALSE, rownames = FALSE, type = "text",
  title = "False Discovery Rate (Benjamini–Hochberg) within Trust Family",
  digits = 3,
  notes = c(
    "Entries show ITT effects and interaction terms (Treatment × 2018 election reminder) on family of trust outcomes.",
    "q-values are Benjamini–Hochberg FDR-adjusted within the trust family.",
    "Covariates include marital status and number of children."
  ),
  notes.append = FALSE
)




#  --------------------------------------------------------------------------- ##
## Appendix Section G: Follow-up Survey Experiment Results                      # 
#  --------------------------------------------------------------------------- ##

# Short variables for summary statistics table
covariates_num <- c(
  # demographic
  "male","urban_binary", "periurban_binary", "discuss_politics_ord","smartphone_binary",
  "registered_binary","education_ord","ever_married","has_children_binary",
  "age_final",
  # province binaries
  "province_eastern",  "province_northwest", "province_northern", "province_southern", "province_western",
  # party proxy dummies
  "party_SLPP","party_APC","party_SwingMixed",
  # Languages spoken
  "krio_speaker", "english_speaker", "mende_speaker", "temne_speaker",  "kono_speaker", "loko_speaker", 
  "limbo_speaker", "koranko_speaker", 
  # comprehension score (pre-treatment attention/comprehension)
  "comp_prop_correct"
  # Languages spoken
)
covariates_num <- intersect(covariates_num, names(analysis_df))

# Stargazer summary of pre-treatment variables
stargazer::stargazer(
  as.data.frame(analysis_df[, covariates_num]),
  type = "text",
  title = "Summary Statistics: Pre-treatment Covariates",
  summary.stat = c("n","mean","sd","min","max"),
  digits = 2,
  out.header = FALSE
)




# ------------------------------------------------------------------------------------------------------------------ 
# Table G2: Treatment Assignment: Counts and Percent -- 

# Treatment assignment table: counts + percents
treat_table <- analysis_df %>%
  filter(!is.na(treatment_arm)) %>%
  count(treatment_arm) %>%
  mutate(Percent = round(100 * n / sum(n), 1)) 

# Output using stargazer
stargazer::stargazer(
  as.data.frame(treat_table),
  type = "text",
  summary = FALSE,
  rownames = FALSE,
  digits = 2,
  title = "Treatment Assignment: Counts and Percent",
  column.labels = c("Treatment Arm","N","Percent"),
  header = FALSE
)





# ------------------------------------------------------------------------------------------------------------------ 
# Table G3: Balance of Pre-treatment Covariates Across Treatment Arms -- 

# Function to compute means for all pretreatment vars by arm + overall mean + omnibus p
balance_one <- function(var, dat) {
  d <- dat %>% dplyr::select(treatment_arm, !!sym(var)) %>% drop_na()
  if (nrow(d) == 0) return(NULL)
  
  # means by arm
  arm_means <- d %>%
    group_by(treatment_arm) %>%
    summarise(mean = mean(.data[[var]]), .groups = "drop") %>%
    tidyr::pivot_wider(names_from = treatment_arm,
                       values_from = mean,
                       names_prefix = "Mean: ") 
  
  # overall mean
  overall <- tibble(`Overall Mean` = mean(d[[var]]))
  
  # omnibus p-value (ANOVA of covariate ~ treatment_arm)
  fit <- lm(d[[var]] ~ d$treatment_arm)
  pval <- anova(fit)[["Pr(>F)"]][1]
  tibble(Variable = var, `Omnibus p` = pval) %>%
    bind_cols(overall, arm_means)
}

# Mapping to variables in Table G1
balance_table <- purrr::map_dfr(covariates_num, balance_one, dat = analysis_df) %>%
  mutate(Variable = dplyr::recode(Variable,
                                  male = "Male",
                                  urban_binary = "Urban resident",
                                  periurban_binary = "Peri-urban resident",
                                  discuss_politics_ord = "Discuss politics often",
                                  smartphone_binary = "Smartphone owner",
                                  registered_binary = "Registered to vote",
                                  education_ord = "Education (ordered)",
                                  ever_married = "Ever married",
                                  has_children_binary = "Has children",
                                  age_final = "Age",
                                  province_eastern = "Eastern Province",
                                  province_northwest = "North-West Province",
                                  province_northern = "Northern Province",
                                  province_southern = "Southern Province",
                                  province_western = "Western Province",
                                  party_SLPP = "Party: SLPP",
                                  party_APC = "Party: APC",
                                  party_SwingMixed = "Party: Swing/Mixed",
                                  krio_speaker = "Speaks Krio",
                                  english_speaker = "Speaks English",
                                  mende_speaker = "Speaks Mende",
                                  temne_speaker = "Speaks Temne",
                                  kono_speaker = "Speaks Kono",
                                  loko_speaker = "Speaks Loko",
                                  koranko_speaker = "Speaks Koranko"
  )) %>%
  # order columns: Variable, Overall, each arm, p-value at end
  dplyr::relocate(Variable, `Overall Mean`) %>%
  dplyr::relocate(`Omnibus p`, .after = dplyr::last_col()) %>%
  # round numeric columns
  mutate(across(where(is.numeric), ~round(.x, 3)))

# Print balance table
stargazer::stargazer(
  as.data.frame(balance_table),
  type = "latex",
  summary = FALSE,
  rownames = FALSE,
  digits = 2,
  title = "Balance of Pre-treatment Covariates Across Treatment Arms",
  header = FALSE
)





# ------------------------------------------------------------------------------------------------------------------ 
# Table G4: Effect of Electoral Rules on Willingness to Wait to Vote (Hours), Moderated by Gender -- 

waitvote_df <- analysis_df %>%
  filter(!is.na(hours_wait_vote), hours_wait_vote <= 80) %>% #filter missing outcome values and remove outliers
  mutate(
    female         = as.integer(female),
    treat_any_pr = as.integer(treat_any_pr),  
    treat_any_fptp = as.integer(treat_any_fptp), 
    treat_any_women = as.integer(treat_any_women), 
    treat_control = as.integer(treat_control), 
    # Set arm factor with FPTP Only as the reference
    treatment_arm = factor(treatment_arm),
    treatment_arm = fct_relevel(
      treatment_arm,
      "FPTP Only", "Pure Control", "FPTP + Women", "Women Only",
      "PR Only","PR + Women","PR + 12% Threshold",
      "PR + 1% Thresh + Women","PR + 12% Thresh + Women"
    )
  )

# Column (1) compares PR + 12% Threshold vs. FPTP Only (2 arms)
d1 <- waitvote_df %>%
  filter(treatment_arm %in% c("FPTP Only","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))
m1 <- lm(hours_wait_vote ~ treatment_arm*female, data = d1)

# Column (2) adds Pure Control (3 arms)
d2 <- waitvote_df %>%
  filter(treatment_arm %in% c("FPTP Only","Pure Control","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))
m2 <- lm(hours_wait_vote ~ treatment_arm*female, data = d2)

# Column (3) adds all women-quota info arms (8 arms)
d3 <- waitvote_df %>%
  filter(treatment_arm %in% c(
    "FPTP Only","Pure Control","PR + 12% Threshold",
    "FPTP + Women","Women Only",
    "PR + Women","PR + 1% Thresh + Women","PR + 12% Thresh + Women"
  )) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))
m3 <- lm(hours_wait_vote ~ treatment_arm*female, data = d3)

# Column (4) includes all treatment arms
d4 <- waitvote_df %>%
  filter(treatment_arm %in% c(
    "FPTP Only","Pure Control","FPTP + Women","Women Only",
    "PR Only","PR + Women","PR + 12% Threshold",
    "PR + 1% Thresh + Women","PR + 12% Thresh + Women"
  )) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))
m4 <- lm(hours_wait_vote ~ treatment_arm*female, data = d4)

# Output table
stargazer::stargazer(
  m1, m2, m3, m4,
  type = "text",
  title = "Effect of Electoral Rules on Willingness to Wait to Vote (Hours), Moderated by Gender",
  dep.var.labels = "Hours willing to wait to vote",
  order = c(
    # common to all models first
    "treatment_armPR \\+ 12% Threshold$",
    "^female$",
    "treatment_armPR \\+ 12% Threshold:female$",
    # Pure Control
    "treatment_armPure Control$",
    "treatment_armPure Control:female$",
    # FPTP + Women
    "treatment_armFPTP \\+ Women$",
    "treatment_armFPTP \\+ Women:female$",
    # Women Only
    "treatment_armWomen Only$",
    "treatment_armWomen Only:female$",
    # PR Only
    "treatment_armPR Only$",
    "treatment_armPR Only:female$",
    # PR + Women
    "treatment_armPR \\+ Women$",
    "treatment_armPR \\+ Women:female$",
    # PR + 1% Thresh + Women
    "treatment_armPR \\+ 1% Thresh \\+ Women$",
    "treatment_armPR \\+ 1% Thresh \\+ Women:female$",
    # PR + 12% Thresh + Women
    "treatment_armPR \\+ 12% Thresh \\+ Women$",
    "treatment_armPR \\+ 12% Thresh \\+ Women:female$"
  ),
  covariate.labels = c(
    # common
    "PR + 12\\% Threshold",
    "Female",
    "PR + 12\\% Threshold $\\times$ Female",
    # rest
    "Pure Control",
    "Pure Control $\\times$ Female",
    "FPTP + Women",
    "FPTP + Women $\\times$ Female",
    "Women Only",
    "Women Only $\\times$ Female",
    "PR Only",
    "PR Only $\\times$ Female",
    "PR + Women",
    "PR + Women $\\times$ Female",
    "PR + 1\\% Thresh + Women",
    "PR + 1\\% Thresh + Women $\\times$ Female",
    "PR + 12\\% Thresh + Women",
    "PR + 12\\% Thresh + Women $\\times$ Female"
  ),
  keep.stat = c("n","rsq","adj.rsq","f"),
  intercept.bottom = TRUE,
  no.space = TRUE,
  digits = 3,
  star.cutoffs = c(0.1, 0.05, 0.01),
  header = FALSE,
  omit.table.layout = "n"
)




# ------------------------------------------------------------------------------------------------------------------ 
# Table G5: Effect of Electoral Rules on Trust in Free and Fair Elections -- 

# Trust election is free fair (1-4)
trust_df<- analysis_df %>%
  filter(!is.na(trust_free_fair)) %>% #filter missing outcome values
  mutate(
    treat_any_pr = as.integer(treat_any_pr),  
    treat_any_fptp = as.integer(treat_any_fptp), 
    treat_any_women = as.integer(treat_any_women), 
    treat_control = as.integer(treat_control), 
    # Set arm factor with FPTP Only as the reference
    treatment_arm = factor(treatment_arm),
    treatment_arm = fct_relevel(
      treatment_arm,
      "FPTP Only", "Pure Control", "FPTP + Women", "Women Only",
      "PR Only","PR + Women","PR + 12% Threshold",
      "PR + 1% Thresh + Women","PR + 12% Thresh + Women"
    ),
  )

# Column (1) compares PR + 12% Threshold vs. FPTP Only (2 arms)
d1 <- trust_df %>%
  filter(treatment_arm %in% c("FPTP Only","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))
m1_trust <- lm(trust_free_fair ~ treatment_arm, data = d1)

# Column (2) adds Pure Control (3 arms)
d2 <- trust_df %>%
  filter(treatment_arm %in% c("FPTP Only","Pure Control","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))
m2_trust <- lm(trust_free_fair ~ treatment_arm, data = d2)

# Column (3) adds all women-quota info arms (8 arms)
d3 <- trust_df %>%
  filter(treatment_arm %in% c(
    "FPTP Only","Pure Control","PR + 12% Threshold",
    "FPTP + Women","Women Only",
    "PR + Women","PR + 1% Thresh + Women","PR + 12% Thresh + Women"
  )) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))
m3_trust <- lm(trust_free_fair ~ treatment_arm, data = d3)

# Column (4) includes all treatment arms
d4 <- trust_df %>%
  filter(treatment_arm %in% c(
    "FPTP Only","Pure Control","FPTP + Women","Women Only",
    "PR Only","PR + Women","PR + 12% Threshold",
    "PR + 1% Thresh + Women","PR + 12% Thresh + Women"
  )) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))
m4_trust <- lm(trust_free_fair ~ treatment_arm, data = d4)


# Output table
stargazer::stargazer(
  m1_trust, m2_trust, m3_trust, m4_trust,
  type = "text",
  title = "Effect of Electoral Rules on Trust in Free and Fair Elections",
  dep.var.labels = "Trust election is free fair (1-4)",
  order = c(
    "treatment_armPR \\+ 12% Threshold$",
    "treatment_armPure Control$",
    "treatment_armFPTP \\+ Women$",
    "treatment_armWomen Only$",
    "treatment_armPR Only$",
    "treatment_armPR \\+ Women$",
    "treatment_armPR \\+ 1% Thresh \\+ Women$",
    "treatment_armPR \\+ 12% Thresh \\+ Women$"
  ),
  covariate.labels = c(
    "PR + 12\\% Threshold",
    "Pure Control",
    "FPTP + Women",
    "Women Only",
    "PR Only",
    "PR + Women",
    "PR + 1\\% Thresh + Women",
    "PR + 12\\% Thresh + Women"
  ),
  keep.stat = c("n","rsq","adj.rsq","f"),
  intercept.bottom = TRUE,
  no.space = TRUE,
  digits = 3,
  star.cutoffs = c(0.1, 0.05, 0.01),
  header = FALSE,
  omit.table.layout = "n",
  notes = NULL
)



# ------------------------------------------------------------------------------------------------------------------ 
# Table G6: Effect of Electoral Rules on Trust in Free and Fair Elections, Moderated by Gender -- 


# Column (1) compares PR + 12% Threshold vs. FPTP Only (2 arms)
d1 <- trust_df %>%
  filter(treatment_arm %in% c("FPTP Only","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))
m1_trust <- lm(trust_free_fair ~ treatment_arm*female, data = d1)


# Column (2) adds Pure Control (3 arms)
d2 <- trust_df %>%
  filter(treatment_arm %in% c("FPTP Only","Pure Control","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))
m2_trust <- lm(trust_free_fair ~ treatment_arm*female, data = d2)


# Column (3) adds all women-quota info arms (8 arms)
d3 <- trust_df %>%
  filter(treatment_arm %in% c(
    "FPTP Only","Pure Control","PR + 12% Threshold",
    "FPTP + Women","Women Only",
    "PR + Women","PR + 1% Thresh + Women","PR + 12% Thresh + Women"
  )) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))
m3_trust <- lm(trust_free_fair ~ treatment_arm*female, data = d3)

# Column (4) includes all treatment arms
d4 <- trust_df %>%
  filter(treatment_arm %in% c(
    "FPTP Only","Pure Control","FPTP + Women","Women Only",
    "PR Only","PR + Women","PR + 12% Threshold",
    "PR + 1% Thresh + Women","PR + 12% Thresh + Women"
  )) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))
m4_trust <- lm(trust_free_fair ~ treatment_arm*female, data = d4)

# Output table
stargazer::stargazer(
  m1_trust, m2_trust, m3_trust, m4_trust,
  type = "text",
  title = "Trust Elections Are Free and Fair, Moderated by Gender",
  dep.var.labels = "Trust election is free fair (1-4)",
  order = c(
    "treatment_armPR \\+ 12% Threshold$",
    "^female$",
    "treatment_armPR \\+ 12% Threshold:female$",
    "treatment_armPure Control$",
    "treatment_armPure Control:female$",
    "treatment_armFPTP \\+ Women$",
    "treatment_armFPTP \\+ Women:female$",
    "treatment_armWomen Only$",
    "treatment_armWomen Only:female$",
    "treatment_armPR Only$",
    "treatment_armPR Only:female$",
    "treatment_armPR \\+ Women$",
    "treatment_armPR \\+ Women:female$",
    "treatment_armPR \\+ 1% Thresh \\+ Women$",
    "treatment_armPR \\+ 1% Thresh \\+ Women:female$",
    "treatment_armPR \\+ 12% Thresh \\+ Women$",
    "treatment_armPR \\+ 12% Thresh \\+ Women:female$"
  ),
  covariate.labels = c(
    "PR + 12\\% Threshold",
    "Female",
    "PR + 12\\% Threshold $\\times$ Female",
    "Pure Control",
    "Pure Control $\\times$ Female",
    "FPTP + Women",
    "FPTP + Women $\\times$ Female",
    "Women Only",
    "Women Only $\\times$ Female",
    "PR Only",
    "PR Only $\\times$ Female",
    "PR + Women",
    "PR + Women $\\times$ Female",
    "PR + 1\\% Thresh + Women",
    "PR + 1\\% Thresh + Women $\\times$ Female",
    "PR + 12\\% Thresh + Women",
    "PR + 12\\% Thresh + Women $\\times$ Female"
  ),
  keep.stat = c("n","rsq","adj.rsq","f"),
  intercept.bottom = TRUE,
  no.space = TRUE,
  digits = 3,
  star.cutoffs = c(0.1, 0.05, 0.01),
  header = FALSE,
  notes = "", notes.append = FALSE
)





# ------------------------------------------------------------------------------------------------------------------ 
# Table G7: Priority if Elected: Country-wide Development -- 

df_cw_e <- analysis_df %>%
  filter(!is.na(priority_elected_country_wide_development)) %>%
  mutate(
    treatment_arm = factor(treatment_arm),
    treatment_arm = fct_relevel(
      treatment_arm,
      "FPTP Only", "Pure Control", "FPTP + Women", "Women Only",
      "PR Only", "PR + Women", "PR + 12% Threshold",
      "PR + 1% Thresh + Women", "PR + 12% Thresh + Women"
    )
  )

# Column (1) compares PR + 12% Threshold vs. FPTP Only (2 arms)
d1_cw_e <- df_cw_e %>%
  filter(treatment_arm %in% c("FPTP Only","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))
m1_cw_e <- lm(priority_elected_country_wide_development ~ treatment_arm, data = d1_cw_e)

# Column (2) adds Pure Control (3 arms)
d2_cw_e <- df_cw_e %>%
  filter(treatment_arm %in% c("FPTP Only","Pure Control","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))
m2_cw_e <- lm(priority_elected_country_wide_development ~ treatment_arm, data = d2_cw_e)

# Column (3) adds all women-quota info arms (8 arms)
d3_cw_e <- df_cw_e %>%
  filter(treatment_arm %in% c(
    "FPTP Only","Pure Control","PR + 12% Threshold",
    "FPTP + Women","Women Only",
    "PR + Women","PR + 1% Thresh + Women","PR + 12% Thresh + Women"
  )) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))
m3_cw_e <- lm(priority_elected_country_wide_development ~ treatment_arm, data = d3_cw_e)

# Column (4) includes all treatment arms
d4_cw_e <- df_cw_e %>%
  filter(treatment_arm %in% c(
    "FPTP Only","Pure Control","FPTP + Women","Women Only",
    "PR Only","PR + Women","PR + 12% Threshold",
    "PR + 1% Thresh + Women","PR + 12% Thresh + Women"
  )) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))
m4_cw_e <- lm(priority_elected_country_wide_development ~ treatment_arm, data = d4_cw_e)

# Output table
d4_cw_e <- df_cw_e %>%
  filter(treatment_arm %in% c(
    "FPTP Only","Pure Control","FPTP + Women","Women Only",
    "PR Only","PR + Women","PR + 12% Threshold",
    "PR + 1% Thresh + Women","PR + 12% Thresh + Women"
  )) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))
m4_cw_e <- lm(priority_elected_country_wide_development ~ treatment_arm, data = d4_cw_e)

stargazer::stargazer(
  m1_cw_e, m2_cw_e, m3_cw_e, m4_cw_e,
  type = "text",
  title = "Priority if Elected: Country-wide Development",
  dep.var.labels = "Candidate will choose country-wide development, if elected)",
  order = c(
    "treatment_armPR \\+ 12% Threshold$",
    "treatment_armPure Control$",
    "treatment_armFPTP \\+ Women$",
    "treatment_armWomen Only$",
    "treatment_armPR Only$",
    "treatment_armPR \\+ Women$",
    "treatment_armPR \\+ 1% Thresh \\+ Women$",
    "treatment_armPR \\+ 12% Thresh \\+ Women$"
  ),
  covariate.labels = c(
    "PR + 12\\% Threshold",
    "Pure Control",
    "FPTP + Women",
    "Women Only",
    "PR Only",
    "PR + Women",
    "PR + 1\\% Thresh + Women",
    "PR + 12\\% Thresh + Women"
  ),
  keep.stat = c("n","rsq","adj.rsq","f"),
  intercept.bottom = TRUE,
  no.space = TRUE,
  digits = 3,
  star.cutoffs = c(0.1, 0.05, 0.01),
  header = FALSE,
  notes = "", notes.append = FALSE
)



# ------------------------------------------------------------------------------------------------------------------ 
# Table G8: Priority while Campaigning: Country-wide Development -- 

df_cw_c <- analysis_df %>%
  filter(!is.na(priority_campaign_country_wide_development)) %>%
  mutate(
    treatment_arm = factor(treatment_arm),
    treatment_arm = fct_relevel(
      treatment_arm,
      "FPTP Only", "Pure Control", "FPTP + Women", "Women Only",
      "PR Only", "PR + Women", "PR + 12% Threshold",
      "PR + 1% Thresh + Women", "PR + 12% Thresh + Women"
    )
  )

# Column (1) compares PR + 12% Threshold vs. FPTP Only (2 arms)
d1_cw_c <- df_cw_c %>%
  filter(treatment_arm %in% c("FPTP Only","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))
m1_cw_c <- lm(priority_campaign_country_wide_development ~ treatment_arm, data = d1_cw_c)

# Column (2) adds Pure Control (3 arms)
d2_cw_c <- df_cw_c %>%
  filter(treatment_arm %in% c("FPTP Only","Pure Control","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))
m2_cw_c <- lm(priority_campaign_country_wide_development ~ treatment_arm, data = d2_cw_c)

# Column (3) adds all women-quota info arms (8 arms)
d3_cw_c <- df_cw_c %>%
  filter(treatment_arm %in% c(
    "FPTP Only","Pure Control","PR + 12% Threshold",
    "FPTP + Women","Women Only",
    "PR + Women","PR + 1% Thresh + Women","PR + 12% Thresh + Women"
  )) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))
m3_cw_c <- lm(priority_campaign_country_wide_development ~ treatment_arm, data = d3_cw_c)

# Column (4) includes all treatment arms
d4_cw_c <- df_cw_c %>%
  filter(treatment_arm %in% c(
    "FPTP Only","Pure Control","FPTP + Women","Women Only",
    "PR Only","PR + Women","PR + 12% Threshold",
    "PR + 1% Thresh + Women","PR + 12% Thresh + Women"
  )) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))
m4_cw_c <- lm(priority_campaign_country_wide_development ~ treatment_arm, data = d4_cw_c)

# Output table
stargazer::stargazer(
  m1_cw_c, m2_cw_c, m3_cw_c, m4_cw_c,
  type = "text",
  title = "Priority while Campaigning: Country-wide Development",
  dep.var.labels = "Candidate will choose country-wide development, while campaigning.)",
  order = c(
    "treatment_armPR \\+ 12% Threshold$",
    "treatment_armPure Control$",
    "treatment_armFPTP \\+ Women$",
    "treatment_armWomen Only$",
    "treatment_armPR Only$",
    "treatment_armPR \\+ Women$",
    "treatment_armPR \\+ 1% Thresh \\+ Women$",
    "treatment_armPR \\+ 12% Thresh \\+ Women$"
  ),
  covariate.labels = c(
    "PR + 12\\% Threshold",
    "Pure Control",
    "FPTP + Women",
    "Women Only",
    "PR Only",
    "PR + Women",
    "PR + 1\\% Thresh + Women",
    "PR + 12\\% Thresh + Women"
  ),
  keep.stat = c("n","rsq","adj.rsq","f"),
  intercept.bottom = TRUE,
  no.space = TRUE,
  digits = 3,
  star.cutoffs = c(0.1, 0.05, 0.01),
  header = FALSE,
  notes = "", notes.append = FALSE
)



# ------------------------------------------------------------------------------------------------------------------ 
# Table G9: Priority if Elected: Neighborhood/Chiefdom Development -- 

df_nc_e <- analysis_df %>%
  filter(!is.na(priority_elected_neighborhood_chiefdom_development)) %>%
  mutate(
    treatment_arm = factor(treatment_arm),
    treatment_arm = fct_relevel(
      treatment_arm,
      "FPTP Only", "Pure Control", "FPTP + Women", "Women Only",
      "PR Only", "PR + Women", "PR + 12% Threshold",
      "PR + 1% Thresh + Women", "PR + 12% Thresh + Women"
    )
  )

# Column (1) compares PR + 12% Threshold vs. FPTP Only (2 arms)
d1_nc_e <- df_nc_e %>%
  filter(treatment_arm %in% c("FPTP Only","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))
m1_nc_e <- lm(priority_elected_neighborhood_chiefdom_development ~ treatment_arm, data = d1_nc_e)

# Column (2) adds Pure Control (3 arms)
d2_nc_e <- df_nc_e %>%
  filter(treatment_arm %in% c("FPTP Only","Pure Control","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))
m2_nc_e <- lm(priority_elected_neighborhood_chiefdom_development ~ treatment_arm, data = d2_nc_e)

# Column (3) adds all women-quota info arms (8 arms)
d3_nc_e <- df_nc_e %>%
  filter(treatment_arm %in% c(
    "FPTP Only","Pure Control","PR + 12% Threshold",
    "FPTP + Women","Women Only",
    "PR + Women","PR + 1% Thresh + Women","PR + 12% Thresh + Women"
  )) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))
m3_nc_e <- lm(priority_elected_neighborhood_chiefdom_development ~ treatment_arm, data = d3_nc_e)

# Column (4) includes all treatment arms
d4_nc_e <- df_nc_e %>%
  filter(treatment_arm %in% c(
    "FPTP Only","Pure Control","FPTP + Women","Women Only",
    "PR Only","PR + Women","PR + 12% Threshold",
    "PR + 1% Thresh + Women","PR + 12% Thresh + Women"
  )) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))
m4_nc_e <- lm(priority_elected_neighborhood_chiefdom_development ~ treatment_arm, data = d4_nc_e)

# Output table
stargazer::stargazer(
  m1_nc_e, m2_nc_e, m3_nc_e, m4_nc_e,
  type = "text",
  title = "Priority if Elected: Neighborhood/Chiefdom Development",
  dep.var.labels = "Candidate will choose neighborhood/chiefdom development, if elected.)",
  order = c(
    "treatment_armPR \\+ 12% Threshold$",
    "treatment_armPure Control$",
    "treatment_armFPTP \\+ Women$",
    "treatment_armWomen Only$",
    "treatment_armPR Only$",
    "treatment_armPR \\+ Women$",
    "treatment_armPR \\+ 1% Thresh \\+ Women$",
    "treatment_armPR \\+ 12% Thresh \\+ Women$"
  ),
  covariate.labels = c(
    "PR + 12\\% Threshold",
    "Pure Control",
    "FPTP + Women",
    "Women Only",
    "PR Only",
    "PR + Women",
    "PR + 1\\% Thresh + Women",
    "PR + 12\\% Thresh + Women"
  ),
  keep.stat = c("n","rsq","adj.rsq","f"),
  intercept.bottom = TRUE,
  no.space = TRUE,
  digits = 3,
  star.cutoffs = c(0.1, 0.05, 0.01),
  header = FALSE,
  notes = "", notes.append = FALSE
)




# ------------------------------------------------------------------------------------------------------------------ 
# Table G10: Priority while Campaigning: Neighborhood/Chiefdom Development -- 

df_nc_c <- analysis_df %>%
  filter(!is.na(priority_campaign_neighborhood_chiefdom_development)) %>%
  mutate(
    treatment_arm = factor(treatment_arm),
    treatment_arm = fct_relevel(
      treatment_arm,
      "FPTP Only", "Pure Control", "FPTP + Women", "Women Only",
      "PR Only", "PR + Women", "PR + 12% Threshold",
      "PR + 1% Thresh + Women", "PR + 12% Thresh + Women"
    )
  )

# Column (1) compares PR + 12% Threshold vs. FPTP Only (2 arms)
d1_nc_c <- df_nc_c %>%
  filter(treatment_arm %in% c("FPTP Only","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))
m1_nc_c <- lm(priority_campaign_neighborhood_chiefdom_development ~ treatment_arm, data = d1_nc_c)

# Column (2) adds Pure Control (3 arms)
d2_nc_c <- df_nc_c %>%
  filter(treatment_arm %in% c("FPTP Only","Pure Control","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))
m2_nc_c <- lm(priority_campaign_neighborhood_chiefdom_development ~ treatment_arm, data = d2_nc_c)

# Column (3) adds all women-quota info arms (8 arms)
d3_nc_c <- df_nc_c %>%
  filter(treatment_arm %in% c(
    "FPTP Only","Pure Control","PR + 12% Threshold",
    "FPTP + Women","Women Only",
    "PR + Women","PR + 1% Thresh + Women","PR + 12% Thresh + Women"
  )) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))
m3_nc_c <- lm(priority_campaign_neighborhood_chiefdom_development ~ treatment_arm, data = d3_nc_c)

# Column (4) includes all treatment arms
d4_nc_c <- df_nc_c %>%
  filter(treatment_arm %in% c(
    "FPTP Only","Pure Control","FPTP + Women","Women Only",
    "PR Only","PR + Women","PR + 12% Threshold",
    "PR + 1% Thresh + Women","PR + 12% Thresh + Women"
  )) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))
m4_nc_c <- lm(priority_campaign_neighborhood_chiefdom_development ~ treatment_arm, data = d4_nc_c)

# Output table
stargazer::stargazer(
  m1_nc_c, m2_nc_c, m3_nc_c, m4_nc_c,
  type = "text",
  title = "Priority while Campaigning: Neighborhood/Chiefdom Development",
  dep.var.labels = "Candidate will choose neighborhood/chiefdom development, while campaigning.)",
  order = c(
    "treatment_armPR \\+ 12% Threshold$",
    "treatment_armPure Control$",
    "treatment_armFPTP \\+ Women$",
    "treatment_armWomen Only$",
    "treatment_armPR Only$",
    "treatment_armPR \\+ Women$",
    "treatment_armPR \\+ 1% Thresh \\+ Women$",
    "treatment_armPR \\+ 12% Thresh \\+ Women$"
  ),
  covariate.labels = c(
    "PR + 12\\% Threshold",
    "Pure Control",
    "FPTP + Women",
    "Women Only",
    "PR Only",
    "PR + Women",
    "PR + 1\\% Thresh + Women",
    "PR + 12\\% Thresh + Women"
  ),
  keep.stat = c("n","rsq","adj.rsq","f"),
  intercept.bottom = TRUE,
  no.space = TRUE,
  digits = 3,
  star.cutoffs = c(0.1, 0.05, 0.01),
  header = FALSE,
  notes = "", notes.append = FALSE
)




# ------------------------------------------------------------------------------------------------------------------ 
# Table G11: Priority if Elected: District-Level Development --

df_dl_e <- analysis_df %>%
  filter(!is.na(priority_elected_district_level_development)) %>%
  mutate(
    treatment_arm = factor(treatment_arm),
    treatment_arm = fct_relevel(
      treatment_arm,
      "FPTP Only", "Pure Control", "FPTP + Women", "Women Only",
      "PR Only", "PR + Women", "PR + 12% Threshold",
      "PR + 1% Thresh + Women", "PR + 12% Thresh + Women"
    )
  )

# Column (1) compares PR + 12% Threshold vs. FPTP Only (2 arms)
d1_dl_e <- df_dl_e %>%
  filter(treatment_arm %in% c("FPTP Only","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))
m1_dl_e <- lm(priority_elected_district_level_development ~ treatment_arm, data = d1_dl_e)

# Column (2) adds Pure Control (3 arms)
d2_dl_e <- df_dl_e %>%
  filter(treatment_arm %in% c("FPTP Only","Pure Control","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))
m2_dl_e <- lm(priority_elected_district_level_development ~ treatment_arm, data = d2_dl_e)

# Column (3) adds all women-quota info arms (8 arms)
d3_dl_e <- df_dl_e %>%
  filter(treatment_arm %in% c(
    "FPTP Only","Pure Control","PR + 12% Threshold",
    "FPTP + Women","Women Only",
    "PR + Women","PR + 1% Thresh + Women","PR + 12% Thresh + Women"
  )) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))
m3_dl_e <- lm(priority_elected_district_level_development ~ treatment_arm, data = d3_dl_e)

# Column (4) includes all treatment arms
d4_dl_e <- df_dl_e %>%
  filter(treatment_arm %in% c(
    "FPTP Only","Pure Control","FPTP + Women","Women Only",
    "PR Only","PR + Women","PR + 12% Threshold",
    "PR + 1% Thresh + Women","PR + 12% Thresh + Women"
  )) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))
m4_dl_e <- lm(priority_elected_district_level_development ~ treatment_arm, data = d4_dl_e)

# Output table
stargazer::stargazer(
  m1_dl_e, m2_dl_e, m3_dl_e , m4_dl_e,
  type = "text",
  title = "Priority if Elected: District-Level Development",
  dep.var.labels = "Candidate will choose district-level development, if elected.)",
  order = c(
    "treatment_armPR \\+ 12% Threshold$",
    "treatment_armPure Control$",
    "treatment_armFPTP \\+ Women$",
    "treatment_armWomen Only$",
    "treatment_armPR Only$",
    "treatment_armPR \\+ Women$",
    "treatment_armPR \\+ 1% Thresh \\+ Women$",
    "treatment_armPR \\+ 12% Thresh \\+ Women$"
  ),
  covariate.labels = c(
    "PR + 12\\% Threshold",
    "Pure Control",
    "FPTP + Women",
    "Women Only",
    "PR Only",
    "PR + Women",
    "PR + 1\\% Thresh + Women",
    "PR + 12\\% Thresh + Women"
  ),
  keep.stat = c("n","rsq","adj.rsq","f"),
  intercept.bottom = TRUE,
  no.space = TRUE,
  digits = 3,
  star.cutoffs = c(0.1, 0.05, 0.01),
  header = FALSE,
  notes = "", notes.append = FALSE
)




# ------------------------------------------------------------------------------------------------------------------ 
# Table G12: Priority while Campaigning: District-Level Development --

df_dl_c <- analysis_df %>%
  filter(!is.na(priority_campaign_district_level_development)) %>%
  mutate(
    treatment_arm = factor(treatment_arm),
    treatment_arm = fct_relevel(
      treatment_arm,
      "FPTP Only", "Pure Control", "FPTP + Women", "Women Only",
      "PR Only", "PR + Women", "PR + 12% Threshold",
      "PR + 1% Thresh + Women", "PR + 12% Thresh + Women"
    )
  )

# Column (1) compares PR + 12% Threshold vs. FPTP Only (2 arms)
d1_dl_c <- df_dl_c %>%
  filter(treatment_arm %in% c("FPTP Only","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))
m1_dl_c <- lm(priority_campaign_district_level_development ~ treatment_arm, data = d1_dl_c)

# Column (2) adds Pure Control (3 arms)
d2_dl_c <- df_dl_c %>%
  filter(treatment_arm %in% c("FPTP Only","Pure Control","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))
m2_dl_c <- lm(priority_campaign_district_level_development ~ treatment_arm, data = d2_dl_c)

# Column (3) adds all women-quota info arms (8 arms)
d3_dl_c <- df_dl_c %>%
  filter(treatment_arm %in% c(
    "FPTP Only","Pure Control","PR + 12% Threshold",
    "FPTP + Women","Women Only",
    "PR + Women","PR + 1% Thresh + Women","PR + 12% Thresh + Women"
  )) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))
m3_dl_c <- lm(priority_campaign_district_level_development ~ treatment_arm, data = d3_dl_c)

# Column (4) includes all treatment arms
d4_dl_c <- df_dl_c %>%
  filter(treatment_arm %in% c(
    "FPTP Only","Pure Control","FPTP + Women","Women Only",
    "PR Only","PR + Women","PR + 12% Threshold",
    "PR + 1% Thresh + Women","PR + 12% Thresh + Women"
  )) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))
m4_dl_c <- lm(priority_campaign_district_level_development ~ treatment_arm, data = d4_dl_c)

# Output table
stargazer::stargazer(
  m1_dl_c, m2_dl_c, m3_dl_c, m4_dl_c,
  type = "text",
  title = "Priority while Campaignin: District-Level Development",
  dep.var.labels = "Candidate will choose district-level development, while campaigning.)",
  order = c(
    "treatment_armPR \\+ 12% Threshold$",
    "treatment_armPure Control$",
    "treatment_armFPTP \\+ Women$",
    "treatment_armWomen Only$",
    "treatment_armPR Only$",
    "treatment_armPR \\+ Women$",
    "treatment_armPR \\+ 1% Thresh \\+ Women$",
    "treatment_armPR \\+ 12% Thresh \\+ Women$"
  ),
  covariate.labels = c(
    "PR + 12\\% Threshold",
    "Pure Control",
    "FPTP + Women",
    "Women Only",
    "PR Only",
    "PR + Women",
    "PR + 1\\% Thresh + Women",
    "PR + 12\\% Thresh + Women"
  ),
  keep.stat = c("n","rsq","adj.rsq","f"),
  intercept.bottom = TRUE,
  no.space = TRUE,
  digits = 3,
  star.cutoffs = c(0.1, 0.05, 0.01),
  header = FALSE,
  notes = "", notes.append = FALSE
)



# ------------------------------------------------------------------------------------------------------------------ 
# Table G13: Priority if Elected: Party-Leader Relationships --

df_pl_e <- analysis_df %>%
  filter(!is.na(priority_elected_party_leader_relationships)) %>%
  mutate(
    treatment_arm = factor(treatment_arm),
    treatment_arm = fct_relevel(
      treatment_arm,
      "FPTP Only", "Pure Control", "FPTP + Women", "Women Only",
      "PR Only", "PR + Women", "PR + 12% Threshold",
      "PR + 1% Thresh + Women", "PR + 12% Thresh + Women"
    )
  )

# Column (1) compares PR + 12% Threshold vs. FPTP Only (2 arms)
d1_pl_e <- df_pl_e %>%
  filter(treatment_arm %in% c("FPTP Only","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))
m1_pl_e <- lm(priority_elected_party_leader_relationships ~ treatment_arm, data = d1_pl_e)

# Column (2) adds Pure Control (3 arms)
d2_pl_e <- df_pl_e %>%
  filter(treatment_arm %in% c("FPTP Only","Pure Control","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))
m2_pl_e <- lm(priority_elected_party_leader_relationships ~ treatment_arm, data = d2_pl_e)

# Column (3) adds all women-quota info arms (8 arms)
d3_pl_e <- df_pl_e %>%
  filter(treatment_arm %in% c(
    "FPTP Only","Pure Control","PR + 12% Threshold",
    "FPTP + Women","Women Only",
    "PR + Women","PR + 1% Thresh + Women","PR + 12% Thresh + Women"
  )) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))
m3_pl_e <- lm(priority_elected_party_leader_relationships ~ treatment_arm, data = d3_pl_e)

# Column (4) includes all treatment arms
d4_pl_e <- df_pl_e %>%
  filter(treatment_arm %in% c(
    "FPTP Only","Pure Control","FPTP + Women","Women Only",
    "PR Only","PR + Women","PR + 12% Threshold",
    "PR + 1% Thresh + Women","PR + 12% Thresh + Women"
  )) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))
m4_pl_e <- lm(priority_elected_party_leader_relationships ~ treatment_arm, data = d4_pl_e)

# Output table
stargazer::stargazer(
  m1_pl_e, m2_pl_e,  m3_pl_e, m4_pl_e,
  type = "text",
  title = "Priority if Elected: Party-Leader Relationships",
  dep.var.labels = "Candidate will choose party-leader relationships, if elected.)",
  order = c(
    "treatment_armPR \\+ 12% Threshold$",
    "treatment_armPure Control$",
    "treatment_armFPTP \\+ Women$",
    "treatment_armWomen Only$",
    "treatment_armPR Only$",
    "treatment_armPR \\+ Women$",
    "treatment_armPR \\+ 1% Thresh \\+ Women$",
    "treatment_armPR \\+ 12% Thresh \\+ Women$"
  ),
  covariate.labels = c(
    "PR + 12\\% Threshold",
    "Pure Control",
    "FPTP + Women",
    "Women Only",
    "PR Only",
    "PR + Women",
    "PR + 1\\% Thresh + Women",
    "PR + 12\\% Thresh + Women"
  ),
  keep.stat = c("n","rsq","adj.rsq","f"),
  intercept.bottom = TRUE,
  no.space = TRUE,
  digits = 3,
  star.cutoffs = c(0.1, 0.05, 0.01),
  header = FALSE,
  notes = "", notes.append = FALSE
)




# ------------------------------------------------------------------------------------------------------------------ 
# Table G14: Priority while Campaigning: Party-Leader Relationships --

df_pl_c <- analysis_df %>%
  filter(!is.na(priority_campaign_party_leader_relationships)) %>%
  mutate(
    treatment_arm = factor(treatment_arm),
    treatment_arm = fct_relevel(
      treatment_arm,
      "FPTP Only", "Pure Control", "FPTP + Women", "Women Only",
      "PR Only", "PR + Women", "PR + 12% Threshold",
      "PR + 1% Thresh + Women", "PR + 12% Thresh + Women"
    )
  )

# Column (1) compares PR + 12% Threshold vs. FPTP Only (2 arms)
d1_pl_c <- df_pl_c %>%
  filter(treatment_arm %in% c("FPTP Only","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))
m1_pl_c <- lm(priority_campaign_party_leader_relationships ~ treatment_arm, data = d1_pl_c)

# Column (2) adds Pure Control (3 arms)
d2_pl_c <- df_pl_c %>%
  filter(treatment_arm %in% c("FPTP Only","Pure Control","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))
m2_pl_c <- lm(priority_campaign_party_leader_relationships ~ treatment_arm, data = d2_pl_c)

# Column (3) adds all women-quota info arms (8 arms)
d3_pl_c <- df_pl_c %>%
  filter(treatment_arm %in% c(
    "FPTP Only","Pure Control","PR + 12% Threshold",
    "FPTP + Women","Women Only",
    "PR + Women","PR + 1% Thresh + Women","PR + 12% Thresh + Women"
  )) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))
m3_pl_c <- lm(priority_campaign_party_leader_relationships ~ treatment_arm, data = d3_pl_c)

# Column (4) includes all treatment arms
d4_pl_c <- df_pl_c %>%
  filter(treatment_arm %in% c(
    "FPTP Only","Pure Control","FPTP + Women","Women Only",
    "PR Only","PR + Women","PR + 12% Threshold",
    "PR + 1% Thresh + Women","PR + 12% Thresh + Women"
  )) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))
m4_pl_c <- lm(priority_campaign_party_leader_relationships ~ treatment_arm, data = d4_pl_c)

# Output table
stargazer::stargazer(
  m1_pl_c, m2_pl_c,  m3_pl_c, m4_pl_c,
  type = "text",
  title = "Priority while Campaigning: Party-Leader Relationships",
  dep.var.labels = "Candidate will choose party-leader relationships, while campaigning.",
  order = c(
    "treatment_armPR \\+ 12% Threshold$",
    "treatment_armPure Control$",
    "treatment_armFPTP \\+ Women$",
    "treatment_armWomen Only$",
    "treatment_armPR Only$",
    "treatment_armPR \\+ Women$",
    "treatment_armPR \\+ 1% Thresh \\+ Women$",
    "treatment_armPR \\+ 12% Thresh \\+ Women$"
  ),
  covariate.labels = c(
    "PR + 12\\% Threshold",
    "Pure Control",
    "FPTP + Women",
    "Women Only",
    "PR Only",
    "PR + Women",
    "PR + 1\\% Thresh + Women",
    "PR + 12\\% Thresh + Women"
  ),
  keep.stat = c("n","rsq","adj.rsq","f"),
  intercept.bottom = TRUE,
  no.space = TRUE,
  digits = 3,
  star.cutoffs = c(0.1, 0.05, 0.01),
  header = FALSE,
  notes = "", notes.append = FALSE
)




# ------------------------------------------------------------------------------------------------------------------ 
# Table G15: Priority if Elected: Women-focused Development -- 

df_women_e <- analysis_df %>%
  filter(!is.na(priority_elected_women_focused_development)) %>%
  mutate(
    treatment_arm = factor(treatment_arm),
    treatment_arm = fct_relevel(
      treatment_arm,
      "FPTP Only", "Pure Control", "FPTP + Women", "Women Only",
      "PR Only", "PR + Women", "PR + 12% Threshold",
      "PR + 1% Thresh + Women", "PR + 12% Thresh + Women"
    )
  )

# Column (1) compares PR + 12% Threshold vs. FPTP Only (2 arms)
d1_women_e <- df_women_e %>%
  filter(treatment_arm %in% c("FPTP Only","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))
m1_women_e <- lm(priority_elected_women_focused_development ~ treatment_arm, data = d1_women_e)

# Column (2) adds Pure Control (3 arms)
d2_women_e <- df_women_e %>%
  filter(treatment_arm %in% c("FPTP Only","Pure Control","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))
m2_women_e <- lm(priority_elected_women_focused_development ~ treatment_arm, data = d2_women_e)

# Column (3) adds all women-quota info arms (8 arms)
d3_women_e <- df_women_e %>%
  filter(treatment_arm %in% c(
    "FPTP Only","Pure Control","PR + 12% Threshold",
    "FPTP + Women","Women Only",
    "PR + Women","PR + 1% Thresh + Women","PR + 12% Thresh + Women"
  )) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))
m3_women_e <- lm(priority_elected_women_focused_development ~ treatment_arm, data = d3_women_e)

# Column (4) includes all treatment arms
d4_women_e <- df_women_e %>%
  filter(treatment_arm %in% c(
    "FPTP Only","Pure Control","FPTP + Women","Women Only",
    "PR Only","PR + Women","PR + 12% Threshold",
    "PR + 1% Thresh + Women","PR + 12% Thresh + Women"
  )) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))
m4_women_e <- lm(priority_elected_women_focused_development ~ treatment_arm, data = d4_women_e)

# Output table
stargazer::stargazer(
  m1_women_e, m2_women_e, m3_women_e, m4_women_e,
  type = "text",
  title = "Priority if Elected: Women-focused Development",
  dep.var.labels = "Candidate will choose women-focused development (if elected)",
  order = c(
    "treatment_armPR \\+ 12% Threshold$",
    "treatment_armPure Control$",
    "treatment_armFPTP \\+ Women$",
    "treatment_armWomen Only$",
    "treatment_armPR Only$",
    "treatment_armPR \\+ Women$",
    "treatment_armPR \\+ 1% Thresh \\+ Women$",
    "treatment_armPR \\+ 12% Thresh \\+ Women$"
  ),
  covariate.labels = c(
    "PR + 12\\% Threshold",
    "Pure Control",
    "FPTP + Women",
    "Women Only",
    "PR Only",
    "PR + Women",
    "PR + 1\\% Thresh + Women",
    "PR + 12\\% Thresh + Women"
  ),
  keep.stat = c("n","rsq","adj.rsq","f"),
  intercept.bottom = TRUE,
  no.space = TRUE,
  digits = 3,
  star.cutoffs = c(0.1, 0.05, 0.01),
  header = FALSE,
  notes = "", notes.append = FALSE
)




# ------------------------------------------------------------------------------------------------------------------ 
# Table G16: Priority if Elected: Women-Focused Development, Moderated by Gender --

# Note: this table uses the same analysis dataframe (df_women_e) as Table G15.

# Column (1) compares PR + 12% Threshold vs. FPTP Only (2 arms)
d1_women_e <- df_women_e %>%
  filter(treatment_arm %in% c("FPTP Only","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))
m1_women_e2 <- lm(priority_elected_women_focused_development ~ treatment_arm*female, data = d1_women_e) 

# Column (2) adds Pure Control (3 arms)
d2_women_e <- df_women_e %>%
  filter(treatment_arm %in% c("FPTP Only","Pure Control","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))
m2_women_e2 <- lm(priority_elected_women_focused_development ~ treatment_arm*female, data = d2_women_e)

# Column (3) adds all women-quota info arms (8 arms)
d3_women_e <- df_women_e %>%
  filter(treatment_arm %in% c(
    "FPTP Only","Pure Control","PR + 12% Threshold",
    "FPTP + Women","Women Only",
    "PR + Women","PR + 1% Thresh + Women","PR + 12% Thresh + Women"
  )) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))
m3_women_e2 <- lm(priority_elected_women_focused_development ~ treatment_arm*female, data = d3_women_e)

# Column (4) includes all treatment arms
d4_women_e <- df_women_e %>%
  filter(treatment_arm %in% c(
    "FPTP Only","Pure Control","FPTP + Women","Women Only",
    "PR Only","PR + Women","PR + 12% Threshold",
    "PR + 1% Thresh + Women","PR + 12% Thresh + Women"
  )) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))
m4_women_e2 <- lm(priority_elected_women_focused_development ~ treatment_arm*female, data = d4_women_e)

# Output table
stargazer::stargazer(
  m1_women_e2, m2_women_e2, m3_women_e2, m4_women_e2,
  type = "text",
  title = "Priority if Elected: Women-Focused Development, Moderated by Gender",
  dep.var.labels = "Candidate will choose women-focused development (if elected)",
  order = c(
    "treatment_armPR \\+ 12% Threshold$",
    "^female$",
    "treatment_armPR \\+ 12% Threshold:female$",
    "treatment_armPure Control$",
    "treatment_armPure Control:female$",
    "treatment_armFPTP \\+ Women$",
    "treatment_armFPTP \\+ Women:female$",
    "treatment_armWomen Only$",
    "treatment_armWomen Only:female$",
    "treatment_armPR Only$",
    "treatment_armPR Only:female$",
    "treatment_armPR \\+ Women$",
    "treatment_armPR \\+ Women:female$",
    "treatment_armPR \\+ 1% Thresh \\+ Women$",
    "treatment_armPR \\+ 1% Thresh \\+ Women:female$",
    "treatment_armPR \\+ 12% Thresh \\+ Women$",
    "treatment_armPR \\+ 12% Thresh \\+ Women:female$"
  ),
  covariate.labels = c(
    "PR + 12\\% Threshold",
    "Female",
    "PR + 12\\% Threshold $\\times$ Female",
    "Pure Control",
    "Pure Control $\\times$ Female",
    "FPTP + Women",
    "FPTP + Women $\\times$ Female",
    "Women Only",
    "Women Only $\\times$ Female",
    "PR Only",
    "PR Only $\\times$ Female",
    "PR + Women",
    "PR + Women $\\times$ Female",
    "PR + 1\\% Thresh + Women",
    "PR + 1\\% Thresh + Women $\\times$ Female",
    "PR + 12\\% Thresh + Women",
    "PR + 12\\% Thresh + Women $\\times$ Female"
  ),
  keep.stat = c("n","rsq","adj.rsq","f"),
  intercept.bottom = TRUE,
  no.space = TRUE,
  digits = 3,
  star.cutoffs = c(0.1, 0.05, 0.01),
  header = FALSE,
  notes = "", notes.append = FALSE
)




# ------------------------------------------------------------------------------------------------------------------ 
# Table G17: Agreement: My Vote Would Matter in the Election --

df_vm <- analysis_df %>%
  filter(!is.na(slider_vote_matters)) %>%
  mutate(
    treatment_arm = factor(treatment_arm),
    treatment_arm = fct_relevel(
      treatment_arm,
      "FPTP Only","Pure Control","FPTP + Women","Women Only",
      "PR Only","PR + Women","PR + 12% Threshold",
      "PR + 1% Thresh + Women","PR + 12% Thresh + Women"
    )
  )

# Column (1) compares PR + 12% Threshold vs. FPTP Only (2 arms)
d1_vm <- df_vm %>%
  filter(treatment_arm %in% c("FPTP Only","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))
m1_vm <- lm(slider_vote_matters ~ treatment_arm, data = d1_vm)

# Column (2) adds Pure Control (3 arms)
d2_vm <- df_vm %>%
  filter(treatment_arm %in% c("FPTP Only","Pure Control","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))
m2_vm <- lm(slider_vote_matters ~ treatment_arm, data = d2_vm)

# Column (3) adds all women-quota info arms (8 arms)
d3_vm <- df_vm %>%
  filter(treatment_arm %in% c("FPTP Only","Pure Control","PR + 12% Threshold",
                              "FPTP + Women","Women Only",
                              "PR + Women","PR + 1% Thresh + Women","PR + 12% Thresh + Women")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))
m3_vm <- lm(slider_vote_matters ~ treatment_arm, data = d3_vm)

# Column (4) includes all treatment arms
d4_vm <- df_vm %>%
  filter(treatment_arm %in% c("FPTP Only","Pure Control","FPTP + Women","Women Only",
                              "PR Only","PR + Women","PR + 12% Threshold",
                              "PR + 1% Thresh + Women","PR + 12% Thresh + Women")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))
m4_vm <- lm(slider_vote_matters ~ treatment_arm, data = d4_vm)

# Output table
stargazer::stargazer(
  m1_vm, m2_vm, m3_vm, m4_vm,
  type = "text",
  title = "Agreement: My Vote Would Matter in the Election",
  dep.var.labels = "1–10 agreement scale",
  order = c(
    "treatment_armPR \\+ 12% Threshold$",
    "treatment_armPure Control$",
    "treatment_armFPTP \\+ Women$",
    "treatment_armWomen Only$",
    "treatment_armPR Only$",
    "treatment_armPR \\+ Women$",
    "treatment_armPR \\+ 1% Thresh \\+ Women$",
    "treatment_armPR \\+ 12% Thresh \\+ Women$"
  ),
  covariate.labels = c(
    "PR + 12\\% Threshold",
    "Pure Control",
    "FPTP + Women",
    "Women Only",
    "PR Only",
    "PR + Women",
    "PR + 1\\% Thresh + Women",
    "PR + 12\\% Thresh + Women"
  ),
  keep.stat = c("n","rsq","adj.rsq","f"),
  intercept.bottom = TRUE, no.space = TRUE,
  digits = 3, star.cutoffs = c(0.1, 0.05, 0.01),
  header = FALSE, notes = "", notes.append = FALSE
)




# ------------------------------------------------------------------------------------------------------------------ 
# Table G18: Agreement: My Vote Would Matter in the Election, Moderated by Gender --

# Note: This table uses the same analysis dataframe (df_vm) as Table G17.

# Column (1) compares PR + 12% Threshold vs. FPTP Only (2 arms)
d1_vm <- df_vm %>%
  filter(treatment_arm %in% c("FPTP Only","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))
m1_vm2 <- lm(slider_vote_matters ~ treatment_arm*female, data = d1_vm)

# Column (2) adds Pure Control (3 arms)
d2_vm <- df_vm %>%
  filter(treatment_arm %in% c("FPTP Only","Pure Control","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))
m2_vm2 <- lm(slider_vote_matters ~ treatment_arm*female, data = d2_vm)

# Column (3) adds all women-quota info arms (8 arms)
d3_vm <- df_vm %>%
  filter(treatment_arm %in% c("FPTP Only","Pure Control","PR + 12% Threshold",
                              "FPTP + Women","Women Only",
                              "PR + Women","PR + 1% Thresh + Women","PR + 12% Thresh + Women")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))
m3_vm2 <- lm(slider_vote_matters ~ treatment_arm*female, data = d3_vm)

# Column (4) includes all treatment arms
d4_vm <- df_vm %>%
  filter(treatment_arm %in% c("FPTP Only","Pure Control","FPTP + Women","Women Only",
                              "PR Only","PR + Women","PR + 12% Threshold",
                              "PR + 1% Thresh + Women","PR + 12% Thresh + Women")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))
m4_vm2 <- lm(slider_vote_matters ~ treatment_arm*female, data = d4_vm)

# Output table
stargazer::stargazer(
  m1_vm2, m2_vm2, m3_vm2, m4_vm2,
  type = "text",
  title = "Agreement: My Vote Would Matter in the Election, Moderated by Gender",
  dep.var.labels = "1-10 agreement scale",
  order = c(
    # common first
    "treatment_armPR \\+ 12% Threshold$",
    "^female$",
    "treatment_armPR \\+ 12% Threshold:female$",
    # then expand
    "treatment_armPure Control$",
    "treatment_armPure Control:female$",
    "treatment_armFPTP \\+ Women$",
    "treatment_armFPTP \\+ Women:female$",
    "treatment_armWomen Only$",
    "treatment_armWomen Only:female$",
    "treatment_armPR Only$",
    "treatment_armPR Only:female$",
    "treatment_armPR \\+ Women$",
    "treatment_armPR \\+ Women:female$",
    "treatment_armPR \\+ 1% Thresh \\+ Women$",
    "treatment_armPR \\+ 1% Thresh \\+ Women:female$",
    "treatment_armPR \\+ 12% Thresh \\+ Women$",
    "treatment_armPR \\+ 12% Thresh \\+ Women:female$"
  ),
  covariate.labels = c(
    "PR + 12\\% Threshold",
    "Female",
    "PR + 12\\% Threshold $\\times$ Female",
    "Pure Control",
    "Pure Control $\\times$ Female",
    "FPTP + Women",
    "FPTP + Women $\\times$ Female",
    "Women Only",
    "Women Only $\\times$ Female",
    "PR Only",
    "PR Only $\\times$ Female",
    "PR + Women",
    "PR + Women $\\times$ Female",
    "PR + 1\\% Thresh + Women",
    "PR + 1\\% Thresh + Women $\\times$ Female",
    "PR + 12\\% Thresh + Women",
    "PR + 12\\% Thresh + Women $\\times$ Female"
  ),
  keep.stat = c("n","rsq","adj.rsq","f"),
  intercept.bottom = TRUE,
  no.space = TRUE,
  digits = 3,
  star.cutoffs = c(0.1, 0.05, 0.01),
  header = FALSE,
  notes = "", notes.append = FALSE
)




# ------------------------------------------------------------------------------------------------------------------ 
# Table G19: Agreement: There Will Be Good Options for Parties/Candidates -- 

df_go <- analysis_df %>%
  filter(!is.na(slider_good_options)) %>%
  mutate(
    treatment_arm = factor(treatment_arm),
    treatment_arm = fct_relevel(
      treatment_arm,
      "FPTP Only","Pure Control","FPTP + Women","Women Only",
      "PR Only","PR + Women","PR + 12% Threshold",
      "PR + 1% Thresh + Women","PR + 12% Thresh + Women"
    )
  )

# Column (1) compares PR + 12% Threshold vs. FPTP Only (2 arms)
d1_go <- df_go %>%
  filter(treatment_arm %in% c("FPTP Only","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))
m1_go <- lm(slider_good_options ~ treatment_arm, data = d1_go)

# Column (2) adds Pure Control (3 arms)
d2_go <- df_go %>%
  filter(treatment_arm %in% c("FPTP Only","Pure Control","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))
m2_go <- lm(slider_good_options ~ treatment_arm, data = d2_go)

# Column (3) adds all women-quota info arms (8 arms)
d3_go <- df_go %>%
  filter(treatment_arm %in% c("FPTP Only","Pure Control","PR + 12% Threshold",
                              "FPTP + Women","Women Only",
                              "PR + Women","PR + 1% Thresh + Women","PR + 12% Thresh + Women")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))
m3_go <- lm(slider_good_options ~ treatment_arm, data = d3_go)

# Column (4) includes all treatment arms
d4_go <- df_go %>%
  filter(treatment_arm %in% c("FPTP Only","Pure Control","FPTP + Women","Women Only",
                              "PR Only","PR + Women","PR + 12% Threshold",
                              "PR + 1% Thresh + Women","PR + 12% Thresh + Women")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))
m4_go <- lm(slider_good_options ~ treatment_arm, data = d4_go)

# Output table
stargazer::stargazer(
  m1_go, m2_go, m3_go, m4_go,
  type = "text",
  title = "Agreement: There Will Be Good Options for Parties/Candidates",
  dep.var.labels = "1–10 agreement scale",
  order = c(
    "treatment_armPR \\+ 12% Threshold$",
    "treatment_armPure Control$",
    "treatment_armFPTP \\+ Women$",
    "treatment_armWomen Only$",
    "treatment_armPR Only$",
    "treatment_armPR \\+ Women$",
    "treatment_armPR \\+ 1% Thresh \\+ Women$",
    "treatment_armPR \\+ 12% Thresh \\+ Women$"
  ),
  covariate.labels = c(
    "PR + 12\\% Threshold",
    "Pure Control",
    "FPTP + Women",
    "Women Only",
    "PR Only",
    "PR + Women",
    "PR + 1\\% Thresh + Women",
    "PR + 12\\% Thresh + Women"
  ),
  keep.stat = c("n","rsq","adj.rsq","f"),
  intercept.bottom = TRUE, no.space = TRUE,
  digits = 3, star.cutoffs = c(0.1, 0.05, 0.01),
  header = FALSE, notes = "", notes.append = FALSE
)




# ------------------------------------------------------------------------------------------------------------------ 
# Table G20: Agreement: Politics Is Too Complicated to Understand --

df_pc <- analysis_df %>%
  filter(!is.na(slider_politics_complicated)) %>%
  mutate(
    treatment_arm = factor(treatment_arm),
    treatment_arm = fct_relevel(
      treatment_arm,
      "FPTP Only","Pure Control","FPTP + Women","Women Only",
      "PR Only","PR + Women","PR + 12% Threshold",
      "PR + 1% Thresh + Women","PR + 12% Thresh + Women"
    )
  )

# Column (1) compares PR + 12% Threshold vs. FPTP Only (2 arms)
d1_pc <- df_pc %>%
  filter(treatment_arm %in% c("FPTP Only","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))
m1_pc <- lm(slider_politics_complicated ~ treatment_arm, data = d1_pc)

# Column (2) adds Pure Control (3 arms)
d2_pc <- df_pc %>%
  filter(treatment_arm %in% c("FPTP Only","Pure Control","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))
m2_pc <- lm(slider_politics_complicated ~ treatment_arm, data = d2_pc)

# Column (3) adds all women-quota info arms (8 arms)
d3_pc <- df_pc %>%
  filter(treatment_arm %in% c("FPTP Only","Pure Control","PR + 12% Threshold",
                              "FPTP + Women","Women Only",
                              "PR + Women","PR + 1% Thresh + Women","PR + 12% Thresh + Women")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))
m3_pc <- lm(slider_politics_complicated ~ treatment_arm, data = d3_pc)

# Column (4) includes all treatment arms
d4_pc <- df_pc %>%
  filter(treatment_arm %in% c("FPTP Only","Pure Control","FPTP + Women","Women Only",
                              "PR Only","PR + Women","PR + 12% Threshold",
                              "PR + 1% Thresh + Women","PR + 12% Thresh + Women")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))
m4_pc <- lm(slider_politics_complicated ~ treatment_arm, data = d4_pc)

# Output table
stargazer::stargazer(
  m1_pc, m2_pc, m3_pc, m4_pc,
  type = "text",
  title = "Agreement: Politics Is Too Complicated to Understand",
  dep.var.labels = "1–10 agreement scale",
  order = c(
    "treatment_armPR \\+ 12% Threshold$",
    "treatment_armPure Control$",
    "treatment_armFPTP \\+ Women$",
    "treatment_armWomen Only$",
    "treatment_armPR Only$",
    "treatment_armPR \\+ Women$",
    "treatment_armPR \\+ 1% Thresh \\+ Women$",
    "treatment_armPR \\+ 12% Thresh \\+ Women$"
  ),
  covariate.labels = c(
    "PR + 12\\% Threshold",
    "Pure Control",
    "FPTP + Women",
    "Women Only",
    "PR Only",
    "PR + Women",
    "PR + 1\\% Thresh + Women",
    "PR + 12\\% Thresh + Women"
  ),
  keep.stat = c("n","rsq","adj.rsq","f"),
  intercept.bottom = TRUE, no.space = TRUE,
  digits = 3, star.cutoffs = c(0.1, 0.05, 0.01),
  header = FALSE, notes = "", notes.append = FALSE
)




# ------------------------------------------------------------------------------------------------------------------ 
# Table G21: Agreement: Government Is Interested in What People Like Me Think --

df_gi <- analysis_df %>%
  filter(!is.na(slider_govt_interested)) %>%
  mutate(
    treatment_arm = factor(treatment_arm),
    treatment_arm = fct_relevel(
      treatment_arm,
      "FPTP Only","Pure Control","FPTP + Women","Women Only",
      "PR Only","PR + Women","PR + 12% Threshold",
      "PR + 1% Thresh + Women","PR + 12% Thresh + Women"
    )
  )

# Column (1) compares PR + 12% Threshold vs. FPTP Only (2 arms)
d1_gi <- df_gi %>%
  filter(treatment_arm %in% c("FPTP Only","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))
m1_gi <- lm(slider_govt_interested ~ treatment_arm, data = d1_gi)

# Column (2) adds Pure Control (3 arms)
d2_gi <- df_gi %>%
  filter(treatment_arm %in% c("FPTP Only","Pure Control","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))
m2_gi <- lm(slider_govt_interested ~ treatment_arm, data = d2_gi)

# Column (3) adds all women-quota info arms (8 arms)
d3_gi <- df_gi %>%
  filter(treatment_arm %in% c("FPTP Only","Pure Control","PR + 12% Threshold",
                              "FPTP + Women","Women Only",
                              "PR + Women","PR + 1% Thresh + Women","PR + 12% Thresh + Women")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))
m3_gi <- lm(slider_govt_interested ~ treatment_arm, data = d3_gi)

# Column (4) includes all treatment arms
d4_gi <- df_gi %>%
  filter(treatment_arm %in% c("FPTP Only","Pure Control","FPTP + Women","Women Only",
                              "PR Only","PR + Women","PR + 12% Threshold",
                              "PR + 1% Thresh + Women","PR + 12% Thresh + Women")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))
m4_gi <- lm(slider_govt_interested ~ treatment_arm, data = d4_gi)

# Output table
stargazer::stargazer(
  m1_gi, m2_gi, m3_gi, m4_gi,
  type = "text",
  title = "Agreement: Government Is Interested in What People Like Me Think",
  dep.var.labels = "1–10 agreement scale",
  order = c(
    "treatment_armPR \\+ 12% Threshold$",
    "treatment_armPure Control$",
    "treatment_armFPTP \\+ Women$",
    "treatment_armWomen Only$",
    "treatment_armPR Only$",
    "treatment_armPR \\+ Women$",
    "treatment_armPR \\+ 1% Thresh \\+ Women$",
    "treatment_armPR \\+ 12% Thresh \\+ Women$"
  ),
  covariate.labels = c(
    "PR + 12\\% Threshold",
    "Pure Control",
    "FPTP + Women",
    "Women Only",
    "PR Only",
    "PR + Women",
    "PR + 1\\% Thresh + Women",
    "PR + 12\\% Thresh + Women"
  ),
  keep.stat = c("n","rsq","adj.rsq","f"),
  intercept.bottom = TRUE, no.space = TRUE,
  digits = 3, star.cutoffs = c(0.1, 0.05, 0.01),
  header = FALSE, notes = "", notes.append = FALSE
)




# ------------------------------------------------------------------------------------------------------------------ 
# Table G22: Agreement: People Like Me Can Make a Difference in Politics -- 

df_md <- analysis_df %>%
  filter(!is.na(slider_make_difference)) %>%
  mutate(
    treatment_arm = factor(treatment_arm),
    treatment_arm = fct_relevel(
      treatment_arm,
      "FPTP Only","Pure Control","FPTP + Women","Women Only",
      "PR Only","PR + Women","PR + 12% Threshold",
      "PR + 1% Thresh + Women","PR + 12% Thresh + Women"
    )
  )

# Column (1) compares PR + 12% Threshold vs. FPTP Only (2 arms)
d1_md <- df_md %>%
  filter(treatment_arm %in% c("FPTP Only","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))
m1_md <- lm(slider_make_difference ~ treatment_arm, data = d1_md)

# Column (2) adds Pure Control (3 arms)
d2_md <- df_md %>%
  filter(treatment_arm %in% c("FPTP Only","Pure Control","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))
m2_md <- lm(slider_make_difference ~ treatment_arm, data = d2_md)

# Column (3) adds all women-quota info arms (8 arms)
d3_md <- df_md %>%
  filter(treatment_arm %in% c("FPTP Only","Pure Control","PR + 12% Threshold",
                              "FPTP + Women","Women Only",
                              "PR + Women","PR + 1% Thresh + Women","PR + 12% Thresh + Women")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))
m3_md <- lm(slider_make_difference ~ treatment_arm, data = d3_md)

# Column (4) includes all treatment arms
d4_md <- df_md %>%
  filter(treatment_arm %in% c("FPTP Only","Pure Control","FPTP + Women","Women Only",
                              "PR Only","PR + Women","PR + 12% Threshold",
                              "PR + 1% Thresh + Women","PR + 12% Thresh + Women")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))
m4_md <- lm(slider_make_difference ~ treatment_arm, data = d4_md)

# Output table
stargazer::stargazer(
  m1_md, m2_md, m3_md, m4_md,
  type = "text",
  title = "Agreement: People Like Me Can Make a Difference",
  dep.var.labels = "1–10 agreement scale",
  order = c(
    "treatment_armPR \\+ 12% Threshold$",
    "treatment_armPure Control$",
    "treatment_armFPTP \\+ Women$",
    "treatment_armWomen Only$",
    "treatment_armPR Only$",
    "treatment_armPR \\+ Women$",
    "treatment_armPR \\+ 1% Thresh \\+ Women$",
    "treatment_armPR \\+ 12% Thresh \\+ Women$"
  ),
  covariate.labels = c(
    "PR + 12\\% Threshold",
    "Pure Control",
    "FPTP + Women",
    "Women Only",
    "PR Only",
    "PR + Women",
    "PR + 1\\% Thresh + Women",
    "PR + 12\\% Thresh + Women"
  ),
  keep.stat = c("n","rsq","adj.rsq","f"),
  intercept.bottom = TRUE, no.space = TRUE,
  digits = 3, star.cutoffs = c(0.1, 0.05, 0.01),
  header = FALSE, notes = "", notes.append = FALSE
)




# ------------------------------------------------------------------------------------------------------------------ 
# Table G23: Agreement: Election chooses Political Representatives in a Fair Way -- 

df_ef <- analysis_df %>%
  filter(!is.na(slider_election_fair)) %>%
  mutate(
    treatment_arm = factor(treatment_arm),
    treatment_arm = fct_relevel(
      treatment_arm,
      "FPTP Only","Pure Control","FPTP + Women","Women Only",
      "PR Only","PR + Women","PR + 12% Threshold",
      "PR + 1% Thresh + Women","PR + 12% Thresh + Women"
    )
  )

# Column (1) compares PR + 12% Threshold vs. FPTP Only (2 arms)
d1_ef <- df_ef %>%
  filter(treatment_arm %in% c("FPTP Only","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))
m1_ef <- lm(slider_election_fair ~ treatment_arm, data = d1_ef)

# Column (2) adds Pure Control (3 arms)
d2_ef <- df_ef %>%
  filter(treatment_arm %in% c("FPTP Only","Pure Control","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))
m2_ef <- lm(slider_election_fair ~ treatment_arm, data = d2_ef)

# Column (3) adds all women-quota info arms (8 arms)
d3_ef <- df_ef %>%
  filter(treatment_arm %in% c("FPTP Only","Pure Control","PR + 12% Threshold",
                              "FPTP + Women","Women Only",
                              "PR + Women","PR + 1% Thresh + Women","PR + 12% Thresh + Women")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))
m3_ef <- lm(slider_election_fair ~ treatment_arm, data = d3_ef)

# Column (4) includes all treatment arms
d4_ef <- df_ef %>%
  filter(treatment_arm %in% c("FPTP Only","Pure Control","FPTP + Women","Women Only",
                              "PR Only","PR + Women","PR + 12% Threshold",
                              "PR + 1% Thresh + Women","PR + 12% Thresh + Women")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))
m4_ef <- lm(slider_election_fair ~ treatment_arm, data = d4_ef)

# Output table
stargazer::stargazer(
  m1_ef, m2_ef, m3_ef, m4_ef,
  type = "text",
  title = "Agreement: Election chooses Political Representatives in a Fair Way",
  dep.var.labels = "1–10 agreement scale",
  order = c(
    "treatment_armPR \\+ 12% Threshold$",
    "treatment_armPure Control$",
    "treatment_armFPTP \\+ Women$",
    "treatment_armWomen Only$",
    "treatment_armPR Only$",
    "treatment_armPR \\+ Women$",
    "treatment_armPR \\+ 1% Thresh \\+ Women$",
    "treatment_armPR \\+ 12% Thresh \\+ Women$"
  ),
  covariate.labels = c(
    "PR + 12\\% Threshold",
    "Pure Control",
    "FPTP + Women",
    "Women Only",
    "PR Only",
    "PR + Women",
    "PR + 1\\% Thresh + Women",
    "PR + 12\\% Thresh + Women"
  ),
  keep.stat = c("n","rsq","adj.rsq","f"),
  intercept.bottom = TRUE, no.space = TRUE,
  digits = 3, star.cutoffs = c(0.1, 0.05, 0.01),
  header = FALSE, notes = "", notes.append = FALSE
)




# ------------------------------------------------------------------------------------------------------------------ 
# Table G24: Agreement: Women Candidates Are Likely to Be Elected -- 

df_we <- analysis_df %>%
  filter(!is.na(slider_women_elected)) %>%
  mutate(
    treatment_arm = factor(treatment_arm),
    treatment_arm = fct_relevel(
      treatment_arm,
      "FPTP Only","Pure Control","FPTP + Women","Women Only",
      "PR Only","PR + Women","PR + 12% Threshold",
      "PR + 1% Thresh + Women","PR + 12% Thresh + Women"
    )
  )

# Column (1) compares PR + 12% Threshold vs. FPTP Only (2 arms)
d1_we <- df_we %>%
  filter(treatment_arm %in% c("FPTP Only","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))
m1_we <- lm(slider_women_elected ~ treatment_arm, data = d1_we)

# Column (2) adds Pure Control (3 arms)
d2_we <- df_we %>%
  filter(treatment_arm %in% c("FPTP Only","Pure Control","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))
m2_we <- lm(slider_women_elected ~ treatment_arm, data = d2_we)

# Column (3) adds all women-quota info arms (8 arms)
d3_we <- df_we %>%
  filter(treatment_arm %in% c("FPTP Only","Pure Control","PR + 12% Threshold",
                              "FPTP + Women","Women Only",
                              "PR + Women","PR + 1% Thresh + Women","PR + 12% Thresh + Women")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))
m3_we <- lm(slider_women_elected ~ treatment_arm, data = d3_we)

# Column (4) includes all treatment arms
d4_we <- df_we %>%
  filter(treatment_arm %in% c("FPTP Only","Pure Control","FPTP + Women","Women Only",
                              "PR Only","PR + Women","PR + 12% Threshold",
                              "PR + 1% Thresh + Women","PR + 12% Thresh + Women")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))
m4_we <- lm(slider_women_elected ~ treatment_arm, data = d4_we)

# Output table
stargazer::stargazer(
  m1_we, m2_we, m3_we, m4_we,
  type = "text",
  title = "Agreement: Women Candidates Are Likely to Be Elected",
  dep.var.labels = "1–10 agreement scale",
  order = c(
    "treatment_armPR \\+ 12% Threshold$",
    "treatment_armPure Control$",
    "treatment_armFPTP \\+ Women$",
    "treatment_armWomen Only$",
    "treatment_armPR Only$",
    "treatment_armPR \\+ Women$",
    "treatment_armPR \\+ 1% Thresh \\+ Women$",
    "treatment_armPR \\+ 12% Thresh \\+ Women$"
  ),
  covariate.labels = c(
    "PR + 12\\% Threshold",
    "Pure Control",
    "FPTP + Women",
    "Women Only",
    "PR Only",
    "PR + Women",
    "PR + 1\\% Thresh + Women",
    "PR + 12\\% Thresh + Women"
  ),
  keep.stat = c("n","rsq","adj.rsq","f"),
  intercept.bottom = TRUE, no.space = TRUE,
  digits = 3, star.cutoffs = c(0.1, 0.05, 0.01),
  header = FALSE, notes = "", notes.append = FALSE
)



#  ----------------------------------------------------------------------------------------- ##
## Appendix Section G: Weight Sample Regressions (Follow-up Survey Experiment)                # 
#  ----------------------------------------------------------------------------------------- ##

#### Code to Reweight the Survey Experimental Sample to Match the Field Experiment ----------

# Variables to reweight on below:

# Gender - 51% male in field experiment, 80% male in survey

# Language spoken: Krio Speaker, Temne Speaker, Mende Speaker, English Speaker, Other Speaker (proportions) - 
# * Field experiment (target): Krio 42%, Mende 26%, Temne 14%, English 1.5%, Other 16%
# * Survey: Krio 68%, Mende 10%, Temne 6%, English 9%, Other 7%
# Standardizing language variables
analysis_df <- analysis_df %>%
  mutate(
    lang_group = case_when(
      homelanguage_final == "Krio" ~ "Krio",
      homelanguage_final == "Mende" ~ "Mende",
      homelanguage_final == "Temne" ~ "Temne",
      homelanguage_final == "English" ~ "English",
      TRUE ~ "Other"
    )
  )

# Married binary (proportion in sample) - 46% married, 54% not married in field experiment. 28% married in survey.
# Creating a binary marital status variable
analysis_df <- analysis_df %>%
  mutate(
    married_binary = case_when(
      married_final == "Yes, I am married." ~ 1,
      married_final %in% c("No, I'm single and never been married.",
                           "Yes, but I am divorced.",
                           "Yes, but I am separated.",
                           "Yes, but I am widowed.") ~ 0,
      TRUE ~ NA_real_
    )
  )

# Age - Mean 34 in field experiment sample. 29.75 mean in survey experiment.
analysis_df <- analysis_df %>%
  mutate(
    age = as.numeric(age_final)
  )

# College education binary (proportion) - survey is much more educated. ~23% field experiment vs survey ~59%.
# Creating a binary college education variable
analysis_df <- analysis_df %>%
  mutate(
    college = case_when(
      education_final %in% c("Bachelor's degree (College, university, technical or vocational school)",
                             "Postgraduate degree (Master's, PhD, etc)") ~ 1,
      education_final %in% c("Junior secondary school", 
                             "Primary school",
                             "Senior secondary school or high school",
                             "No formal education") ~ 0,
      TRUE ~ NA_real_
    )
  )

# Prepare variables to rake on from the survey experiment sample
if (!"row_id" %in% names(analysis_df)) {
  analysis_df <- analysis_df %>% 
    dplyr::mutate(row_id = dplyr::row_number())   # join key on row ID for merging back weight later
}

rw_df <- analysis_df %>%
  mutate(row_id = row_number()) %>%
  dplyr::select(row_id, male, married_binary, college, age, lang_group) %>%
  filter(!is.na(male),
         !is.na(married_binary),
         !is.na(college),
         !is.na(age),
         !is.na(lang_group)) %>%
  mutate(
    age_c = age - 34   # centering age so target is 0 (mean age = 34)
  )

# Base Survey Design (equal weights = 1, unweighted survey experimental sample)
# ie. starting with all survey experimental observations counting equally, unweighted
des0 <- svydesign(ids = ~1, data = rw_df, weights = ~1)

# Define the field-experiment sample target margins
p_male    <- 0.5088
p_married <- 0.4627
p_college <- 0.215739 + 0.006784  # Bachelor's + Postgrad = 0.222523
p_krio    <- 0.420624
p_mende   <- 0.261872
p_temne   <- 0.141113
p_english <- 0.014925
p_other   <- 1 - (p_krio + p_mende + p_temne + p_english)  # 0.161466 for other languages
# Continuous age target: mean age = 34 → total age = N * 34
N_rake <- nrow(rw_df)   # count of rows raking on
#total_age_target <- N_rake * 34

# Post-stratification to match language margins first 
post_lang <- data.frame(
  lang_group = c("Krio","Mende","Temne","English","Other"),
  Freq       = N_rake * c(p_krio, p_mende, p_temne, p_english, p_other)
)

# Post-stratify to match language distribution exactly
des1 <- postStratify(des0, ~ lang_group, post_lang)

# Use the (post-stratified) weighted N as the anchor for totals
N_anchor <- sum(weights(des1))   #1378, which is the total no. of non-missing rows

# Build population margin dataframes/vector for raking

# Convert proportion targets to totals over current (raked) sample size
# Totals vector:
#  - (Intercept) anchors the total weight
#  - age_c total = 0 enforces mean(age) = 34
pop_totals_step2 <- c(
  `(Intercept)`  = N_anchor,
  male           = N_anchor * p_male,
  married_binary = N_anchor * p_married,
  college        = N_anchor * p_college,
  age_c          = 0
)

# Raking using calibrate for multiple other variables (gender, marital status, college education, age)
calib_formula <- ~ 1 + male + married_binary + college + age_c

calib_des <- calibrate(
  design   = des1,
  formula    = calib_formula,
  population = pop_totals_step2,
  bounds     = c(0.1, 10),   # lower/upper bounds on weight ratios - caps how extreme any weight can become relative to its base weight. Final weights must be within this range.
  method     = "linear"   
)

# Pull the weights back into the analysis dataframe
rw_weights <- tibble(
  row_id = rw_df$row_id,
  weight_rake = as.numeric(weights(calib_des))
)

analysis_df <- analysis_df %>%
  left_join(rw_weights, by = "row_id") %>%
  mutate(
    # For rows not in rw_df (had missing on rake vars), keep weight = 1
    weight_rake = ifelse(is.na(weight_rake), 1, weight_rake)
  )

# Diagnostics for weighting
summary(analysis_df$weight_rake)
quantile(analysis_df$weight_rake, probs = c(0, .01, .05, .5, .95, .99, 1), na.rm = TRUE)

# Effective sample size (ESS) - A higher ESS relative to the actual sample size signifies more informative data
w <- analysis_df$weight_rake
N_eff <- (sum(w, na.rm = TRUE)^2) / sum(w^2, na.rm = TRUE)
N_raw <- sum(!is.na(w))
tibble_ESS <- tibble(N_raw, N_eff, ratio = N_eff/N_raw)
print(tibble_ESS)

des_final <- svydesign(ids = ~1, data = analysis_df, weights = ~weight_rake)
svymean(~ male + married_binary + college + age, design = des_final, na.rm = TRUE) # eyeballing that target proportions met

lang_tab_w <- svytable(~ lang_group, design = des_final)
prop.table(lang_tab_w) #eyeballing language proportions after reweighting

# For comparison, unweighted figures:
mean(analysis_df$male, na.rm = TRUE)
mean(analysis_df$married_binary, na.rm = TRUE)
mean(analysis_df$college, na.rm = TRUE)
mean(analysis_df$age, na.rm = TRUE)
prop.table(table(analysis_df$lang_group, useNA = "no"))


# Trimming to prevent extreme weights
analysis_df <- analysis_df %>%
  mutate(weight_trim5 = pmin(weight_rake, 5))  # capping upper bound for rake weights at 5

analysis_df <- analysis_df %>%
  mutate(weight_trim10 = pmin(weight_rake, 10))  # capping upper bound for rake weights at 10

# Effective sample size after trimming
for (wvar in c("weight_rake", "weight_trim5", "weight_trim10")) {
  w <- analysis_df[[wvar]]
  N_eff <- (sum(w, na.rm=TRUE)^2) / sum(w^2, na.rm=TRUE)
  N_raw <- sum(!is.na(w))
  cat(wvar, ": ESS =", N_eff, "ratio =", N_eff/N_raw, "\n")
}

# Compare weighted vs. unweighted margins
des_trim5  <- svydesign(ids=~1, data=analysis_df, weights=~weight_trim5)
des_trim10 <- svydesign(ids=~1, data=analysis_df, weights=~weight_trim10)

svymean(~ male + married_binary + college + age, design=des_trim5)
prop.table(svytable(~ lang_group, design=des_trim5))

svymean(~ male + married_binary + college + age, design=des_trim10)
prop.table(svytable(~ lang_group, design=des_trim10))

# Going with trimming upper bound of weights at 5 to trade-off bias (distance from target) vs variance (ESS)
with(analysis_df, weighted.mean(married_binary, weight_trim5, na.rm = TRUE)) # 42% married vs 46% in field experiment
with(analysis_df, weighted.mean(college, weight_trim5, na.rm = TRUE)) #27% college educated vs 23% in field experiment
with(analysis_df, weighted.mean(male, weight_trim5, na.rm = TRUE))  #56% male vs 51% male in field experiment
with(analysis_df, weighted.mean(age, weight_trim5, na.rm = TRUE)) #32.96 mean age vs 34 in field experiment
prop.table(xtabs(weight_trim5 ~ lang_group, data = analysis_df))



# ------------------------------------------------------------------------------------------------------------------
# Table G25: Field Experimental Sample vs. Online Survey Sample (unweighted vs. weighted) -- 

# Helper to format percents 
fmt_pct <- function(x) sprintf("%.1f\\%%", 100 * x)
fmt_num <- function(x) sprintf("%.2f", x)

# Ordering the language factor variable
lang_levels <- c("Krio","Mende","Temne","English","Other")
analysis_df <- analysis_df %>%
  mutate(lang_group = factor(lang_group, levels = lang_levels))

# Field experimental targets
targets <- tibble::tibble(
  metric   = c("Male", "Married", "College", "Mean age",
               "Krio", "Mende", "Temne", "English", "Other"),
  target   = c(p_male, p_married, p_college, 34,
               p_krio,  p_mende,  p_temne,  p_english, p_other),
  is_pct   = c(TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE)
)

## Unweighted survey margins
unw_bin_age <- tibble::tibble(
  metric   = c("Male","Married","College","Mean age"),
  unweighted = c(
    mean(analysis_df$male, na.rm = TRUE),
    mean(analysis_df$married_binary, na.rm = TRUE),
    mean(analysis_df$college, na.rm = TRUE),
    mean(analysis_df$age, na.rm = TRUE)
  ),
  is_pct   = c(TRUE, TRUE, TRUE, FALSE)
)
unw_lang <- prop.table(table(analysis_df$lang_group, useNA = "no"))
unw_lang <- tibble::tibble(
  metric     = names(unw_lang),
  unweighted = as.numeric(unw_lang),
  is_pct     = TRUE
)
unweighted_all <- bind_rows(unw_bin_age, unw_lang)

## Weighted (trim=5) survey margins
w <- analysis_df$weight_trim5
w_bin_age <- tibble::tibble(
  metric   = c("Male","Married","College","Mean age"),
  weighted_trim5 = c(
    weighted.mean(analysis_df$male,            w, na.rm = TRUE),
    weighted.mean(analysis_df$married_binary,  w, na.rm = TRUE),
    weighted.mean(analysis_df$college,         w, na.rm = TRUE),
    weighted.mean(analysis_df$age,             w, na.rm = TRUE)
  ),
  is_pct   = c(TRUE, TRUE, TRUE, FALSE)
)
w_lang_tab <- xtabs(weight_trim5 ~ lang_group, data = analysis_df)
w_lang_prop <- prop.table(w_lang_tab)
w_lang <- tibble::tibble(
  metric         = names(w_lang_prop),
  weighted_trim5 = as.numeric(w_lang_prop),
  is_pct         = TRUE
)
weighted_all <- bind_rows(w_bin_age, w_lang)

## Join targets + unweighted + weighted
summary_tbl <- targets %>%
  left_join(unweighted_all %>% dplyr::select(metric, unweighted), by = "metric") %>%
  left_join(weighted_all   %>% dplyr::select(metric, weighted_trim5), by = "metric") %>%
  mutate(
    Target      = ifelse(is_pct, fmt_pct(target),   fmt_num(target)),
    Unweighted  = ifelse(is_pct, fmt_pct(unweighted), fmt_num(unweighted)),
    `Weighted (trim=5)` = ifelse(is_pct, fmt_pct(weighted_trim5), fmt_num(weighted_trim5)),
    `|Weighted - Target|` = ifelse(
      is_pct, fmt_pct(abs(weighted_trim5 - target)), fmt_num(abs(weighted_trim5 - target))
    )
  ) %>%
  dplyr::select(
    Metric = metric, Target, Unweighted, `Weighted (trim=5)`, `|Weighted - Target|`
  )

print(knitr::kable(summary_tbl, format = "latex", booktabs = TRUE, escape = FALSE,
                   caption = "Field Experimental Sample vs. Online Survey Sample (unweighted vs. weighted)."))




# ------------------------------------------------------------------------------------------------------------------
# Creating a function for the subsequent weighted regressions (Tables 26-33)
USE_WEIGHTS <- TRUE            # turn weighting on/off globally
WEIGHT_VAR  <- "weight_trim5"  # which column to use as weights when on
USE_SURVEY_DESIGN <- TRUE  # set TRUE to use survey::svyglm instead of lm()

fit <- function(formula, data, family = NULL) {
  stopifnot(is.data.frame(data))
  if (USE_SURVEY_DESIGN) {
    # Build weights formula from the string name, "~ weight_trim5"
    w_formula <- if (USE_WEIGHTS) as.formula(paste0("~", WEIGHT_VAR)) else ~1
    des <- survey::svydesign(ids = ~1, data = data, weights = w_formula)
    if (is.null(family)) family <- gaussian()
    survey::svyglm(formula, design = des, family = family)
  } else {
    if (is.null(family)) {
      if (USE_WEIGHTS) lm(formula, data = data, weights = data[[WEIGHT_VAR]])
      else             lm(formula, data = data)
    } else {
      if (USE_WEIGHTS) glm(formula, data = data, family = family, weights = data[[WEIGHT_VAR]])
      else             glm(formula, data = data, family = family)
    }
  }
}

# supply SEs from svyglm/lm to stargazer
se_list <- function(models) lapply(models, function(m) sqrt(diag(vcov(m))))




# ------------------------------------------------------------------------------------------------------------------ 
# Table G26: Effect on Willingness to Wait to Vote (Hours), Moderated by Gender — Weighted --

waitvote_df <- analysis_df %>%
  filter(!is.na(hours_wait_vote), hours_wait_vote <= 80) %>% #filter missing outcome values and remove outliers
  mutate(
    female         = as.integer(female),
    treat_any_pr = as.integer(treat_any_pr),  
    treat_any_fptp = as.integer(treat_any_fptp), 
    treat_any_women = as.integer(treat_any_women), 
    treat_control = as.integer(treat_control), 
    # Set arm factor with FPTP Only as the reference
    treatment_arm = factor(treatment_arm),
    treatment_arm = fct_relevel(
      treatment_arm,
      "FPTP Only", "Pure Control", "FPTP + Women", "Women Only",
      "PR Only","PR + Women","PR + 12% Threshold",
      "PR + 1% Thresh + Women","PR + 12% Thresh + Women"
    )
  )

# Column (1) compares PR + 12% Threshold vs. FPTP Only (2 arms)
d1 <- waitvote_df %>%
  filter(treatment_arm %in% c("FPTP Only","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))

# Column (2) adds Pure Control (3 arms)
d2 <- waitvote_df %>%
  filter(treatment_arm %in% c("FPTP Only","Pure Control","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))

# Column (3) adds all women-quota info arms (8 arms)
d3 <- waitvote_df %>%
  filter(treatment_arm %in% c(
    "FPTP Only","Pure Control","PR + 12% Threshold",
    "FPTP + Women","Women Only",
    "PR + Women","PR + 1% Thresh + Women","PR + 12% Thresh + Women"
  )) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))

# Column (4) includes all treatment arms
d4 <- waitvote_df %>%
  filter(treatment_arm %in% c(
    "FPTP Only","Pure Control","FPTP + Women","Women Only",
    "PR Only","PR + Women","PR + 12% Threshold",
    "PR + 1% Thresh + Women","PR + 12% Thresh + Women"
  )) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))

# Weighted regressions
m1_w <- fit(hours_wait_vote ~ treatment_arm*female, data = d1)  
m2_w <- fit(hours_wait_vote ~ treatment_arm*female, data = d2)
m3_w <- fit(hours_wait_vote ~ treatment_arm*female, data = d3)
m4_w <- fit(hours_wait_vote ~ treatment_arm*female, data = d4)
mods_w <- list(m1_w, m2_w, m3_w, m4_w)
ses_w  <- se_list(mods_w)

# Output table
stargazer::stargazer(
  mods_w,
  se = ses_w,
  type = "text",
  title = "Effect of Electoral Rules on Willingness to Wait to Vote (Hours), Moderated by Gender — Weighted",
  dep.var.labels = "Hours willing to wait to vote",
  order = c(
    # common to all models first
    "treatment_armPR \\+ 12% Threshold$",
    "^female$",
    "treatment_armPR \\+ 12% Threshold:female$",
    # Pure Control
    "treatment_armPure Control$",
    "treatment_armPure Control:female$",
    # FPTP + Women
    "treatment_armFPTP \\+ Women$",
    "treatment_armFPTP \\+ Women:female$",
    # Women Only
    "treatment_armWomen Only$",
    "treatment_armWomen Only:female$",
    # PR Only
    "treatment_armPR Only$",
    "treatment_armPR Only:female$",
    # PR + Women
    "treatment_armPR \\+ Women$",
    "treatment_armPR \\+ Women:female$",
    # PR + 1% Thresh + Women
    "treatment_armPR \\+ 1% Thresh \\+ Women$",
    "treatment_armPR \\+ 1% Thresh \\+ Women:female$",
    # PR + 12% Thresh + Women
    "treatment_armPR \\+ 12% Thresh \\+ Women$",
    "treatment_armPR \\+ 12% Thresh \\+ Women:female$"
  ),
  covariate.labels = c(
    # common
    "PR + 12\\% Threshold",
    "Female",
    "PR + 12\\% Threshold $\\times$ Female",
    # rest
    "Pure Control",
    "Pure Control $\\times$ Female",
    "FPTP + Women",
    "FPTP + Women $\\times$ Female",
    "Women Only",
    "Women Only $\\times$ Female",
    "PR Only",
    "PR Only $\\times$ Female",
    "PR + Women",
    "PR + Women $\\times$ Female",
    "PR + 1\\% Thresh + Women",
    "PR + 1\\% Thresh + Women $\\times$ Female",
    "PR + 12\\% Thresh + Women",
    "PR + 12\\% Thresh + Women $\\times$ Female"
  ),
  keep.stat = c("n"),                  
  omit.stat = c("rsq","adj.rsq","f"),
  intercept.bottom = TRUE,
  no.space = TRUE,
  digits = 3,
  star.cutoffs = c(0.1, 0.05, 0.01),
  header = FALSE,
  omit.table.layout = "n",
  add.lines = list(
    c("Reference Group", "FPTP Only", "FPTP Only", "FPTP Only", "FPTP Only"),
    c("Sample (No. of Treatment Arms)", "2", "3", "8", "Full"),
    c("Weighted Sample?", "Yes", "Yes","Yes","Yes")
  )
)




# ------------------------------------------------------------------------------------------------------------------ 
# Table G27: Trust Elections Are Free and Fair — Weighted --

trust_df<- analysis_df %>%
  filter(!is.na(trust_free_fair)) %>%
  mutate(
    treat_any_pr = as.integer(treat_any_pr),  
    treat_any_fptp = as.integer(treat_any_fptp), 
    treat_any_women = as.integer(treat_any_women), 
    treat_control = as.integer(treat_control), 
    treatment_arm = factor(treatment_arm),
    treatment_arm = fct_relevel(
      treatment_arm,
      "FPTP Only", "Pure Control", "FPTP + Women", "Women Only",
      "PR Only","PR + Women","PR + 12% Threshold",
      "PR + 1% Thresh + Women","PR + 12% Thresh + Women"
    ),
  )

# Column (1) compares PR + 12% Threshold vs. FPTP Only (2 arms)
d1 <- trust_df %>%
  filter(treatment_arm %in% c("FPTP Only","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))

# Column (2) adds Pure Control (3 arms)
d2 <- trust_df %>%
  filter(treatment_arm %in% c("FPTP Only","Pure Control","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))

# Column (3) adds all women-quota info arms (8 arms)
d3 <- trust_df %>%
  filter(treatment_arm %in% c(
    "FPTP Only","Pure Control","PR + 12% Threshold",
    "FPTP + Women","Women Only",
    "PR + Women","PR + 1% Thresh + Women","PR + 12% Thresh + Women"
  )) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))

# Column (4) includes all treatment arms
d4 <- trust_df %>%
  filter(treatment_arm %in% c(
    "FPTP Only","Pure Control","FPTP + Women","Women Only",
    "PR Only","PR + Women","PR + 12% Threshold",
    "PR + 1% Thresh + Women","PR + 12% Thresh + Women"
  )) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))

# Weighted trust regressions 
m1_trust_w <- fit(trust_free_fair ~ treatment_arm, data = d1)
m2_trust_w <- fit(trust_free_fair ~ treatment_arm, data = d2)
m3_trust_w <- fit(trust_free_fair ~ treatment_arm, data = d3)
m4_trust_w <- fit(trust_free_fair ~ treatment_arm, data = d4)
mods_trust_w <- list(m1_trust_w, m2_trust_w, m3_trust_w, m4_trust_w)
ses_trust_w  <- se_list(mods_trust_w)

# Output table
stargazer::stargazer(
  mods_trust_w,
  se = ses_trust_w,
  type = "text",
  title = "Trust Elections Are Free and Fair — Weighted",
  dep.var.labels = "Trust in free and fair elections",
  order = c(
    "treatment_armPR \\+ 12% Threshold$",
    "treatment_armPure Control$",
    "treatment_armFPTP \\+ Women$",
    "treatment_armWomen Only$",
    "treatment_armPR Only$",
    "treatment_armPR \\+ Women$",
    "treatment_armPR \\+ 1% Thresh \\+ Women$",
    "treatment_armPR \\+ 12% Thresh \\+ Women$"
  ),
  covariate.labels = c(
    "PR + 12\\% Threshold",
    "Pure Control",
    "FPTP + Women",
    "Women Only",
    "PR Only",
    "PR + Women",
    "PR + 1\\% Thresh + Women",
    "PR + 12\\% Thresh + Women"
  ),
  keep.stat = c("n"),
  omit.stat = c("rsq","adj.rsq","f","ll","aic"),
  intercept.bottom = TRUE,
  no.space = TRUE,
  digits = 3,
  star.cutoffs = c(0.1, 0.05, 0.01),
  header = FALSE,
  omit.table.layout = "n",
  add.lines = list(
    c("Reference Group", "FPTP Only", "FPTP Only", "FPTP Only", "FPTP Only"),
    c("Sample (No. of Treatment Arms)", "2", "3", "8", "Full"),
    c("Weighted Sample?", "Yes", "Yes","Yes","Yes")
  )
)




# ------------------------------------------------------------------------------------------------------------------ 
# Table G28: Trust Elections Are Free and Fair, Moderated by Gender — Weighted --

# Note: Uses the same analysis dataframes as Table G27.

# Weighted trust regressions, moderated by gender
m1_trust_w <- fit(trust_free_fair ~ treatment_arm*female, data = d1)
m2_trust_w <- fit(trust_free_fair ~ treatment_arm*female, data = d2)
m3_trust_w <- fit(trust_free_fair ~ treatment_arm*female, data = d3)
m4_trust_w <- fit(trust_free_fair ~ treatment_arm*female, data = d4)
mods_trust_w <- list(m1_trust_w, m2_trust_w, m3_trust_w, m4_trust_w)
ses_trust_w  <- se_list(mods_trust_w)

# Output table
stargazer::stargazer(
  mods_trust_w,
  se = ses_trust_w,
  type = "text",
  title = "Trust Elections Are Free and Fair, Moderated by Gender — Weighted",
  dep.var.labels = "Trust in free and fair elections",
  order = c(
    "treatment_armPR \\+ 12% Threshold$",
    "^female$",
    "treatment_armPR \\+ 12% Threshold:female$",
    "treatment_armPure Control$",
    "treatment_armPure Control:female$",
    "treatment_armFPTP \\+ Women$",
    "treatment_armFPTP \\+ Women:female$",
    "treatment_armWomen Only$",
    "treatment_armWomen Only:female$",
    "treatment_armPR Only$",
    "treatment_armPR Only:female$",
    "treatment_armPR \\+ Women$",
    "treatment_armPR \\+ Women:female$",
    "treatment_armPR \\+ 1% Thresh \\+ Women$",
    "treatment_armPR \\+ 1% Thresh \\+ Women:female$",
    "treatment_armPR \\+ 12% Thresh \\+ Women$",
    "treatment_armPR \\+ 12% Thresh \\+ Women:female$"
  ),
  covariate.labels = c(
    "PR + 12\\% Threshold",
    "Female",
    "PR + 12\\% Threshold $\\times$ Female",
    "Pure Control",
    "Pure Control $\\times$ Female",
    "FPTP + Women",
    "FPTP + Women $\\times$ Female",
    "Women Only",
    "Women Only $\\times$ Female",
    "PR Only",
    "PR Only $\\times$ Female",
    "PR + Women",
    "PR + Women $\\times$ Female",
    "PR + 1\\% Thresh + Women",
    "PR + 1\\% Thresh + Women $\\times$ Female",
    "PR + 12\\% Thresh + Women",
    "PR + 12\\% Thresh + Women $\\times$ Female"
  ),
  keep.stat = c("n"),
  omit.stat = c("rsq","adj.rsq","f"),
  intercept.bottom = TRUE,
  no.space = TRUE,
  digits = 3,
  star.cutoffs = c(0.1, 0.05, 0.01),
  header = FALSE,
  omit.table.layout = "n",
  add.lines = list(
    c("Reference Group", "FPTP Only", "FPTP Only", "FPTP Only", "FPTP Only"),
    c("Sample (No. of Treatment Arms)", "2", "3", "8", "Full"),
    c("Weighted Sample?", "Yes", "Yes", "Yes", "Yes")
  )
)




# ------------------------------------------------------------------------------------------------------------------ 
# Table G29: Priority while Campaigning: Neighborhood/Chiefdom Development — Weighted --

df_nc_c <- analysis_df %>%
  filter(!is.na(priority_campaign_neighborhood_chiefdom_development)) %>%
  mutate(
    treatment_arm = factor(treatment_arm),
    treatment_arm = fct_relevel(
      treatment_arm,
      "FPTP Only", "Pure Control", "FPTP + Women", "Women Only",
      "PR Only", "PR + Women", "PR + 12% Threshold",
      "PR + 1% Thresh + Women", "PR + 12% Thresh + Women"
    )
  )

# Column (1) compares PR + 12% Threshold vs. FPTP Only (2 arms)
d1_nc_c <- df_nc_c %>%
  filter(treatment_arm %in% c("FPTP Only","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))

# Column (2) adds Pure Control (3 arms)
d2_nc_c <- df_nc_c %>%
  filter(treatment_arm %in% c("FPTP Only","Pure Control","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))

# Column (3) adds all women-quota info arms (8 arms)
d3_nc_c <- df_nc_c %>%
  filter(treatment_arm %in% c(
    "FPTP Only","Pure Control","PR + 12% Threshold",
    "FPTP + Women","Women Only",
    "PR + Women","PR + 1% Thresh + Women","PR + 12% Thresh + Women"
  )) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))

# Column (4) includes all treatment arms
d4_nc_c <- df_nc_c %>%
  filter(treatment_arm %in% c(
    "FPTP Only","Pure Control","FPTP + Women","Women Only",
    "PR Only","PR + Women","PR + 12% Threshold",
    "PR + 1% Thresh + Women","PR + 12% Thresh + Women"
  )) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))

## Weighted regressions - neighborhood/chiefdom issues while campaigning
m1_nc_c_w <- fit(priority_campaign_neighborhood_chiefdom_development ~ treatment_arm, data = d1_nc_c)
m2_nc_c_w <- fit(priority_campaign_neighborhood_chiefdom_development ~ treatment_arm, data = d2_nc_c)
m3_nc_c_w <- fit(priority_campaign_neighborhood_chiefdom_development ~ treatment_arm, data = d3_nc_c)
m4_nc_c_w <- fit(priority_campaign_neighborhood_chiefdom_development ~ treatment_arm, data = d4_nc_c)
mods_nc_c_w <- list(m1_nc_c_w, m2_nc_c_w, m3_nc_c_w, m4_nc_c_w)
ses_nc_c_w  <- se_list(mods_nc_c_w)

# Output table
stargazer::stargazer(
  mods_nc_c_w,
  se = ses_nc_c_w,
  type = "text",
  title = "Priority while Campaigning: Neighborhood/Chiefdom Development — Weighted",
  dep.var.labels = "Pr(Neighborhood/Chiefdom development while campaigning)",
  order = c(
    "treatment_armPR \\+ 12% Threshold$",
    "treatment_armPure Control$",
    "treatment_armFPTP \\+ Women$",
    "treatment_armWomen Only$",
    "treatment_armPR Only$",
    "treatment_armPR \\+ Women$",
    "treatment_armPR \\+ 1% Thresh \\+ Women$",
    "treatment_armPR \\+ 12% Thresh \\+ Women$"
  ),
  covariate.labels = c(
    "PR + 12\\% Threshold",
    "Pure Control",
    "FPTP + Women",
    "Women Only",
    "PR Only",
    "PR + Women",
    "PR + 1\\% Thresh + Women",
    "PR + 12\\% Thresh + Women"
  ),
  keep.stat = c("n"),
  omit.stat = c("rsq","adj.rsq","f","ll","aic"),
  intercept.bottom = TRUE,
  no.space = TRUE,
  digits = 3,
  star.cutoffs = c(0.1, 0.05, 0.01),
  header = FALSE,
  omit.table.layout = "n",
  add.lines = list(
    c("Reference Group", "FPTP Only", "FPTP Only", "FPTP Only", "FPTP Only"),
    c("Sample (No. of Treatment Arms)", "2", "3", "8", "Full"),
    c("Weighted Sample?", "Yes","Yes","Yes","Yes")
  )
)





# ------------------------------------------------------------------------------------------------------------------ 
# Table G30: Priority while Campaigning: Party–Leader Relationships — Weighted --

df_pl_c <- analysis_df %>%
  filter(!is.na(priority_campaign_party_leader_relationships)) %>%
  mutate(
    treatment_arm = factor(treatment_arm),
    treatment_arm = fct_relevel(
      treatment_arm,
      "FPTP Only", "Pure Control", "FPTP + Women", "Women Only",
      "PR Only", "PR + Women", "PR + 12% Threshold",
      "PR + 1% Thresh + Women", "PR + 12% Thresh + Women"
    )
  )

# Column (1) compares PR + 12% Threshold vs. FPTP Only (2 arms)
d1_pl_c <- df_pl_c %>%
  filter(treatment_arm %in% c("FPTP Only","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))

# Column (2) adds Pure Control (3 arms)
d2_pl_c <- df_pl_c %>%
  filter(treatment_arm %in% c("FPTP Only","Pure Control","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))

# Column (3) adds all women-quota info arms (8 arms)
d3_pl_c <- df_pl_c %>%
  filter(treatment_arm %in% c(
    "FPTP Only","Pure Control","PR + 12% Threshold",
    "FPTP + Women","Women Only",
    "PR + Women","PR + 1% Thresh + Women","PR + 12% Thresh + Women"
  )) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))

# Column (4) includes all treatment arms
d4_pl_c <- df_pl_c %>%
  filter(treatment_arm %in% c(
    "FPTP Only","Pure Control","FPTP + Women","Women Only",
    "PR Only","PR + Women","PR + 12% Threshold",
    "PR + 1% Thresh + Women","PR + 12% Thresh + Women"
  )) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))

## Weighted regressions - party leadership relationships prioritize while campaigning
m1_pl_c_w <- fit(priority_campaign_party_leader_relationships ~ treatment_arm, data = d1_pl_c)
m2_pl_c_w <- fit(priority_campaign_party_leader_relationships ~ treatment_arm, data = d2_pl_c)
m3_pl_c_w <- fit(priority_campaign_party_leader_relationships ~ treatment_arm, data = d3_pl_c)
m4_pl_c_w <- fit(priority_campaign_party_leader_relationships ~ treatment_arm, data = d4_pl_c)
mods_pl_c_w <- list(m1_pl_c_w, m2_pl_c_w, m3_pl_c_w, m4_pl_c_w)
ses_pl_c_w  <- se_list(mods_pl_c_w)

# Output table
stargazer::stargazer(
  mods_pl_c_w,
  se = ses_pl_c_w,
  type = "text",
  title = "Priority while Campaigning: Party–Leader Relationships — Weighted",
  dep.var.labels = "Pr(Party–leader relationships while campaigning)",
  order = c(
    "treatment_armPR \\+ 12% Threshold$",
    "treatment_armPure Control$",
    "treatment_armFPTP \\+ Women$",
    "treatment_armWomen Only$",
    "treatment_armPR Only$",
    "treatment_armPR \\+ Women$",
    "treatment_armPR \\+ 1% Thresh \\+ Women$",
    "treatment_armPR \\+ 12% Thresh \\+ Women$"
  ),
  covariate.labels = c(
    "PR + 12\\% Threshold",
    "Pure Control",
    "FPTP + Women",
    "Women Only",
    "PR Only",
    "PR + Women",
    "PR + 1\\% Thresh + Women",
    "PR + 12\\% Thresh + Women"
  ),
  keep.stat = c("n"),
  omit.stat = c("rsq","adj.rsq","f","ll","aic"),
  intercept.bottom = TRUE,
  no.space = TRUE,
  digits = 3,
  star.cutoffs = c(0.1, 0.05, 0.01),
  header = FALSE,
  omit.table.layout = "n",
  add.lines = list(
    c("Reference Group", "FPTP Only", "FPTP Only", "FPTP Only", "FPTP Only"),
    c("Sample (No. of Treatment Arms)", "2", "3", "8", "Full"),
    c("Weighted Sample?", "Yes","Yes","Yes","Yes")
  )
)




# ------------------------------------------------------------------------------------------------------------------ 
# Table G31: Priority if Elected: Women-Focused Development, Moderated by Gender — Weighted --

df_women_e <- analysis_df %>%
  filter(!is.na(priority_elected_women_focused_development)) %>%
  mutate(
    treatment_arm = factor(treatment_arm),
    treatment_arm = fct_relevel(
      treatment_arm,
      "FPTP Only", "Pure Control", "FPTP + Women", "Women Only",
      "PR Only", "PR + Women", "PR + 12% Threshold",
      "PR + 1% Thresh + Women", "PR + 12% Thresh + Women"
    )
  )

# Column (1) compares PR + 12% Threshold vs. FPTP Only (2 arms)
d1_women_e <- df_women_e %>%
  filter(treatment_arm %in% c("FPTP Only","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))

# Column (2) adds Pure Control (3 arms)
d2_women_e <- df_women_e %>%
  filter(treatment_arm %in% c("FPTP Only","Pure Control","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))

# Column (3) adds all women-quota info arms (8 arms)
d3_women_e <- df_women_e %>%
  filter(treatment_arm %in% c(
    "FPTP Only","Pure Control","PR + 12% Threshold",
    "FPTP + Women","Women Only",
    "PR + Women","PR + 1% Thresh + Women","PR + 12% Thresh + Women"
  )) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))

# Column (4) includes all treatment arms
d4_women_e <- df_women_e %>%
  filter(treatment_arm %in% c(
    "FPTP Only","Pure Control","FPTP + Women","Women Only",
    "PR Only","PR + Women","PR + 12% Threshold",
    "PR + 1% Thresh + Women","PR + 12% Thresh + Women"
  )) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm, "FPTP Only"))

## Weighted Regressions - Women-Centered Development Prioritize if Elected
m1_women_e_w <- fit(priority_elected_women_focused_development ~ treatment_arm*female, data = d1_women_e)
m2_women_e_w <- fit(priority_elected_women_focused_development ~ treatment_arm*female, data = d2_women_e)
m3_women_e_w <- fit(priority_elected_women_focused_development ~ treatment_arm*female, data = d3_women_e)
m4_women_e_w <- fit(priority_elected_women_focused_development ~ treatment_arm*female, data = d4_women_e)
mods_women_e_w <- list(m1_women_e_w, m2_women_e_w, m3_women_e_w, m4_women_e_w)
ses_women_e_w  <- se_list(mods_women_e_w)

# Output table
stargazer::stargazer(
  mods_women_e_w,
  se = ses_women_e_w,
  type = "text",
  title = "Priority if Elected: Women-Focused Development, Moderated by Gender — Weighted",
  dep.var.labels = "Pr(Women-focused development if elected)",
  order = c(
    # common to all models first
    "treatment_armPR \\+ 12% Threshold$",
    "^female$",
    "treatment_armPR \\+ 12% Threshold:female$",
    "treatment_armPure Control$",
    "treatment_armPure Control:female$",
    "treatment_armFPTP \\+ Women$",
    "treatment_armFPTP \\+ Women:female$",
    "treatment_armWomen Only$",
    "treatment_armWomen Only:female$",
    "treatment_armPR Only$",
    "treatment_armPR Only:female$",
    "treatment_armPR \\+ Women$",
    "treatment_armPR \\+ Women:female$",
    "treatment_armPR \\+ 1% Thresh \\+ Women$",
    "treatment_armPR \\+ 1% Thresh \\+ Women:female$",
    "treatment_armPR \\+ 12% Thresh \\+ Women$",
    "treatment_armPR \\+ 12% Thresh \\+ Women:female$"
  ),
  covariate.labels = c(
    "PR + 12\\% Threshold",
    "Female",
    "PR + 12\\% Threshold $\\times$ Female",
    
    "Pure Control",
    "Pure Control $\\times$ Female",
    
    "FPTP + Women",
    "FPTP + Women $\\times$ Female",
    
    "Women Only",
    "Women Only $\\times$ Female",
    
    "PR Only",
    "PR Only $\\times$ Female",
    
    "PR + Women",
    "PR + Women $\\times$ Female",
    
    "PR + 1\\% Thresh + Women",
    "PR + 1\\% Thresh + Women $\\times$ Female",
    
    "PR + 12\\% Thresh + Women",
    "PR + 12\\% Thresh + Women $\\times$ Female"
  ),
  keep.stat = c("n"),
  omit.stat = c("rsq","adj.rsq","f","ll","aic"),
  intercept.bottom = TRUE,
  no.space = TRUE,
  digits = 3,
  star.cutoffs = c(0.1, 0.05, 0.01),
  header = FALSE,
  omit.table.layout = "n",
  add.lines = list(
    c("Reference Group", "FPTP Only", "FPTP Only", "FPTP Only", "FPTP Only"),
    c("Sample (No. of Treatment Arms)", "2", "3", "8", "Full"),
    c("Weighted Sample?", "Yes","Yes","Yes","Yes")
  )
)




# ------------------------------------------------------------------------------------------------------------------ 
# Table G32: Agreement: My Vote Would Matter in the Election — Weighted --

df_vm <- analysis_df %>%
  filter(!is.na(slider_vote_matters)) %>%
  mutate(
    treatment_arm = factor(treatment_arm),
    treatment_arm = fct_relevel(
      treatment_arm,
      "FPTP Only","Pure Control","FPTP + Women","Women Only",
      "PR Only","PR + Women","PR + 12% Threshold",
      "PR + 1% Thresh + Women","PR + 12% Thresh + Women"
    )
  )

# Column (1) compares PR + 12% Threshold vs. FPTP Only (2 arms)
d1_vm <- df_vm %>%
  filter(treatment_arm %in% c("FPTP Only","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))

# Column (2) adds Pure Control (3 arms)
d2_vm <- df_vm %>%
  filter(treatment_arm %in% c("FPTP Only","Pure Control","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))

# Column (3) adds all women-quota info arms (8 arms)
d3_vm <- df_vm %>%
  filter(treatment_arm %in% c("FPTP Only","Pure Control","PR + 12% Threshold",
                              "FPTP + Women","Women Only",
                              "PR + Women","PR + 1% Thresh + Women","PR + 12% Thresh + Women")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))

# Column (4) includes all treatment arms
d4_vm <- df_vm %>%
  filter(treatment_arm %in% c("FPTP Only","Pure Control","FPTP + Women","Women Only",
                              "PR Only","PR + Women","PR + 12% Threshold",
                              "PR + 1% Thresh + Women","PR + 12% Thresh + Women")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))

## Weighted regressions: my vote will matter (1-10 agreement scale)
m1_vm_nomod_w <- fit(slider_vote_matters ~ treatment_arm, data = d1_vm)
m2_vm_nomod_w <- fit(slider_vote_matters ~ treatment_arm, data = d2_vm)
m3_vm_nomod_w <- fit(slider_vote_matters ~ treatment_arm, data = d3_vm)
m4_vm_nomod_w <- fit(slider_vote_matters ~ treatment_arm, data = d4_vm)
mods_vm_nomod_w <- list(m1_vm_nomod_w, m2_vm_nomod_w, m3_vm_nomod_w, m4_vm_nomod_w)
ses_vm_nomod_w  <- se_list(mods_vm_nomod_w)

# Output table
stargazer::stargazer(
  mods_vm_nomod_w,
  se = ses_vm_nomod_w,
  type = "text",
  title = "Agreement: My Vote Would Matter in the Election — Weighted",
  dep.var.labels = "1–10 agreement scale",
  order = c(
    "treatment_armPR \\+ 12% Threshold$",
    "treatment_armPure Control$",
    "treatment_armFPTP \\+ Women$",
    "treatment_armWomen Only$",
    "treatment_armPR Only$",
    "treatment_armPR \\+ Women$",
    "treatment_armPR \\+ 1% Thresh \\+ Women$",
    "treatment_armPR \\+ 12% Thresh \\+ Women$"
  ),
  covariate.labels = c(
    "PR + 12\\% Threshold",
    "Pure Control",
    "FPTP + Women",
    "Women Only",
    "PR Only",
    "PR + Women",
    "PR + 1\\% Thresh + Women",
    "PR + 12\\% Thresh + Women"
  ),
  keep.stat = c("n"),
  omit.stat = c("rsq","adj.rsq","f","ll","aic"),
  intercept.bottom = TRUE,
  no.space = TRUE,
  digits = 3,
  star.cutoffs = c(0.1, 0.05, 0.01),
  header = FALSE,
  omit.table.layout = "n",
  add.lines = list(
    c("Reference Group", "FPTP Only", "FPTP Only", "FPTP Only", "FPTP Only"),
    c("Sample (No. of Treatment Arms)", "2", "3", "8", "Full"),
    c("Weighted Sample?", "Yes","Yes","Yes","Yes")
  )
)





# ------------------------------------------------------------------------------------------------------------------ 
# Table G33: Agreement: Election Chooses Political Representatives in a Fair Way — Weighted --

df_ef <- analysis_df %>%
  filter(!is.na(slider_election_fair)) %>%
  mutate(
    treatment_arm = factor(treatment_arm),
    treatment_arm = fct_relevel(
      treatment_arm,
      "FPTP Only","Pure Control","FPTP + Women","Women Only",
      "PR Only","PR + Women","PR + 12% Threshold",
      "PR + 1% Thresh + Women","PR + 12% Thresh + Women"
    )
  )

# Column (1) compares PR + 12% Threshold vs. FPTP Only (2 arms)
d1_ef <- df_ef %>%
  filter(treatment_arm %in% c("FPTP Only","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))

# Column (2) adds Pure Control (3 arms)
d2_ef <- df_ef %>%
  filter(treatment_arm %in% c("FPTP Only","Pure Control","PR + 12% Threshold")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))

# Column (3) adds all women-quota info arms (8 arms)
d3_ef <- df_ef %>%
  filter(treatment_arm %in% c("FPTP Only","Pure Control","PR + 12% Threshold",
                              "FPTP + Women","Women Only",
                              "PR + Women","PR + 1% Thresh + Women","PR + 12% Thresh + Women")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))

# Column (4) includes all treatment arms
d4_ef <- df_ef %>%
  filter(treatment_arm %in% c("FPTP Only","Pure Control","FPTP + Women","Women Only",
                              "PR Only","PR + Women","PR + 12% Threshold",
                              "PR + 1% Thresh + Women","PR + 12% Thresh + Women")) %>%
  mutate(treatment_arm = fct_relevel(treatment_arm,"FPTP Only"))

## Weighted Regression: Election Chooses Candidates in a Fair Way 
m1_ef_w <- fit(slider_election_fair ~ treatment_arm, data = d1_ef)
m2_ef_w <- fit(slider_election_fair ~ treatment_arm, data = d2_ef)
m3_ef_w <- fit(slider_election_fair ~ treatment_arm, data = d3_ef)
m4_ef_w <- fit(slider_election_fair ~ treatment_arm, data = d4_ef)
mods_ef_w <- list(m1_ef_w, m2_ef_w, m3_ef_w, m4_ef_w)
ses_ef_w  <- se_list(mods_ef_w)

# Output table
stargazer::stargazer(
  mods_ef_w,
  se = ses_ef_w,
  type = "text",
  title = "Agreement: Election Chooses Political Representatives in a Fair Way — Weighted",
  dep.var.labels = "1–10 agreement scale",
  order = c(
    "treatment_armPR \\+ 12% Threshold$",
    "treatment_armPure Control$",
    "treatment_armFPTP \\+ Women$",
    "treatment_armWomen Only$",
    "treatment_armPR Only$",
    "treatment_armPR \\+ Women$",
    "treatment_armPR \\+ 1% Thresh \\+ Women$",
    "treatment_armPR \\+ 12% Thresh \\+ Women$"
  ),
  covariate.labels = c(
    "PR + 12\\% Threshold",
    "Pure Control",
    "FPTP + Women",
    "Women Only",
    "PR Only",
    "PR + Women",
    "PR + 1\\% Thresh + Women",
    "PR + 12\\% Thresh + Women"
  ),
  keep.stat = c("n"),
  omit.stat = c("rsq","adj.rsq","f","ll","aic"),
  intercept.bottom = TRUE,
  no.space = TRUE,
  digits = 3,
  star.cutoffs = c(0.1, 0.05, 0.01),
  header = FALSE,
  omit.table.layout = "n",
  add.lines = list(
    c("Reference Group", "FPTP Only", "FPTP Only", "FPTP Only", "FPTP Only"),
    c("Sample (No. of Treatment Arms)", "2", "3", "8", "Full"),
    c("Weighted Sample?", "Yes","Yes","Yes","Yes")
  )
)




#  ----------------------------------------------------------------------------------- ##
## Appendix Section J: A Possibly Complementary Relationship between Elite Mechanisms   #
#                                                                  and voter learning   #
#  ----------------------------------------------------------------------------------- ##

### Calculate district-level seats for each party in 2018 under hypothetical district-block PR ###

# Initial seat allocation for each party in a district using floor function (rounding down)
district_aggregates_pr_allocation <- district_aggregates %>%    # Note: district_aggregates is the same object created when producing Table B3
  filter(vote_share >= pr_threshold) %>%  # Filter for parties meeting the threshold in each district
  mutate(initial_seats_allocated = floor(vote_share * seats)) %>%
  # Calculate remainders and distribute remaining seats based on the largest remainders
  mutate(remainder = (vote_share * seats) - initial_seats_allocated)

# Calculate total seats initially allocated per district
district_allocated_seats <- district_aggregates_pr_allocation %>%
  group_by(sub) %>%
  summarise(
    total_initial_seats = sum(initial_seats_allocated),
    remaining_seats = first(seats) - sum(initial_seats_allocated)  # Seats left to be allocated
  )


# Adjust the PR seat allocation to ensure all seats are distributed
district_aggregates_pr_allocation <- district_aggregates_pr_allocation %>%
  left_join(district_allocated_seats, by = "sub") %>%
  arrange(sub, desc(remainder)) %>%  # Sort by district and largest remainder
  group_by(sub) %>%
  mutate(
    # Allocate remaining seats based on largest remainders
    seats_allocated = initial_seats_allocated + if_else(row_number() <= remaining_seats, 1, 0)
  ) %>%
  ungroup() %>%
  group_by(sub) %>%
  # Ensure that all district seats are assigned 
  mutate(
    final_seats_allocated = case_when(
      sum(seats_allocated) < first(seats) & remainder == max(remainder) ~ seats_allocated + (first(seats) - sum(seats_allocated)),
      TRUE ~ seats_allocated
    )
  ) %>%
  ungroup()

###  Calculate the Actual 2018 Seat Shares Under FPTP for Each District ###
# One constituency is missing election results from 2018 (Const No. 123 in Western Urban)
# Identified the row with the "-99" constituency and updated it based on this: https://electiondata.io/voter-education/candidates/member-of-parliament
# and this: https://www.parliament.gov.sl/uploads/votes/25%20APRIL%202018%20POSL.pdf
SL_2018_results <- SL_2018_results %>%
  mutate(
    pty = ifelse(cst_n == "Constituency 123", 1, pty),  # Ensure APC is coded correctly
    pty_n = ifelse(cst_n == "Constituency 123", "All People's Congress (APC)", pty_n),  # Ensure the party is APC
    can = ifelse(cst_n == "Constituency 123", "ALHADI LIHADI", can),  # Update the candidate's name
    seat = ifelse(cst_n == "Constituency 123", 1, seat)  # Update the winner of the seat
  )

# Identify the winning parties in each constituency
fptp_seat_wins <- SL_2018_results %>%
  filter(seat == 1) %>%  # Winners are coded as 1 in CLEA data
  group_by(sub, pty_n) %>%  # Group by district and party
  summarise(seats_won = n(), .groups = 'drop')  # Count the number of seats won by each party in each district

# Calculate the total number of constituencies in each district
district_constituency_counts <- SL_2018_results %>%
  group_by(sub) %>%
  summarise(total_constituencies = n_distinct(cst), .groups = 'drop')

# Merge the seat wins with the district constituency counts
fptp_seat_wins <- fptp_seat_wins %>%
  left_join(district_constituency_counts, by = "sub") %>%
  mutate(seat_share = seats_won / total_constituencies)  # Calculate seat share for each party in each district

# Merge FPTP seat shares with PR seat allocations for each party in every district
seat_comparison <- fptp_seat_wins %>%
  full_join(district_aggregates_pr_allocation %>%
              select(sub, pty_n, final_seats_allocated, seats), 
            by = c("sub", "pty_n")) %>%
  mutate(
    # Set FPTP seat share to 0 for parties that didn’t win seats under FPTP
    seats_won = replace_na(seats_won, 0), 
    fptp_seat_share = seats_won / replace_na(total_constituencies, 1),  # Replace NA in total_constituencies with 1 to avoid division errors
    pr_seat_share = final_seats_allocated / seats,  # PR seat share
    seat_share_difference = pr_seat_share - fptp_seat_share  # Difference in seat shares if the switch to PR had happened in 2018
  )

seat_comparison <- fptp_seat_wins %>%
  full_join(district_aggregates_pr_allocation %>%
              select(sub, pty_n, final_seats_allocated, seats), 
            by = c("sub", "pty_n")) %>%
  mutate(
    # Set FPTP seat share to 0 for parties that didn’t win seats under FPTP
    seats_won = replace_na(seats_won, 0), 
    fptp_seat_share = seats_won / replace_na(total_constituencies, 1),  # Replace NA in total_constituencies with 1 to avoid division errors
    
    # Handle cases where PR allocation is NA (i.e., the party didn't cross the threshold)
    final_seats_allocated = replace_na(final_seats_allocated, 0),
    pr_seat_share = final_seats_allocated / replace_na(seats, 1),  # PR seat share
    
    # Calculate the difference in seat shares between FPTP and PR
    seat_share_difference = pr_seat_share - fptp_seat_share
  )

seat_comparison <- seat_comparison %>%
  arrange(sub, pty_n)  # Sort by district and party 

### Calculate District-level Seat Share Difference under PR ###

# Calculate the absolute seat share difference
seat_comparison <- seat_comparison %>%
  mutate(abs_seat_share_difference = abs(seat_share_difference))

# Calculate the district-level maximum difference
district_max_difference <- seat_comparison %>%
  group_by(sub) %>%
  summarise(max_difference = max(abs_seat_share_difference, na.rm = TRUE))

### Merge the district-level seat share differences with the survey data ###

# Create a mapping for district names before merge
district_name_mapping <- tibble(
  district.x = c("bo", "bombali", "bonthe", "falaba", "kailahun", "kambia", "karene", "kenema", 
                 "koinadugu", "kono", "moyamba", "port loko", "pujehun", "tonkolili", 
                 "western rural", "western urban"),
  sub = c("Bo", "Bombali", "Bonthe", "Falaba", "Kailahun", "Kambia", "Karene", "Kenema", 
          "Koinadugu", "Kono", "Moyamba", "Port Loko", "Pujehun", "Tonkolili", 
          "Western Area Rural", "Western Area Urban")
)

# Merge the mapping into the survey data to standardize district names
merged_data <- merged_data %>%
  left_join(district_name_mapping, by = "district.x") %>%
  mutate(district_standardized = sub) %>%  # Create a standardized district variable
  select(-sub)

# # Merge the district-level seat share differences with the survey data
merged_data <- merged_data %>%
  left_join(district_max_difference, by = c("district_standardized" = "sub")) %>%
  select(-district_standardized)





# ------------------------------------------------------------------------------------------------------------------ 
# Figure J1: District-Level Max Seat Share Differences under PR. --

# Convert the districts shapefile to an sf object
districts_sf <- st_as_sf(districts.shp)
districts_sf$ADM2_EN[districts_sf$ADM2_EN=="Fabala"] <- "Falaba" # correcting typo in shapefile

# Merge the district seat share differences with the district boundaries
districts_sf <- merge(districts_sf, district_max_difference, by.x = "ADM2_EN", by.y = "sub")

# Create the map for max seat share difference
ggplot(districts_sf) +
  geom_sf(aes(fill = max_difference), color = "white", size = 0.2) +
  scale_fill_viridis_c(option = "mako", direction = -1,
                       name = "Max Seat Share Diff.") +
  labs(title = "District-Level Max Seat Share Differences under PR",
       subtitle = "Darker colors indicate greater shifts under PR system") +
  theme_minimal() +
  theme(legend.position = "right")




# ------------------------------------------------------------------------------------------------------------------ 
# Table J1: Effects on Participation by Maximum Seat Share Difference under PR and Gender --

# Triple interaction between treatment, gender, and max seat share difference under PR
turnout_gender_max <- lm(would_vote ~ treatment_status * max_difference.y * female + respondent_children_num + married, data = merged_data)
wait_hours_gender_max <- lm(vote_wait_time ~ treatment_status * max_difference.y * female + respondent_children_num + married, data = merged_data)
# Store models as list
participation_max_diff_gender_models <- list(turnout_gender_max, wait_hours_gender_max)

# Output table 
stargazer(participation_max_diff_gender_models, 
          title = "Effects on Participation by Maximum Seat Share Differences and Gender",
          align = TRUE, type = "text")




# ------------------------------------------------------------------------------------------------------------------ 
# Table J2: Treatment Effects on Approval of Appeals (Moderated by Max Seat Share Difference) --

# Regression models with maximum seat share difference interaction terms
targeted_appeal_reg_max <- lm(liked_targeted_appeal ~ treatment_status * max_difference.y + respondent_children_num + married + 
                                party_ID, data = merged_data)

# Output table
stargazer(targeted_appeal_reg_max,
          title = "Treatment Effects on Strong Approval of Appeals Moderated by Maximum Seat Share Differences", align = TRUE, type = "text")






                                              ## End of replication code ##

